在 ForEach-Object -Parallel 块内从自身递归调用函数 - 并行块内无法识别函数

2023-11-29

第一次在这里提问。请善待:)

我试图以并行方式递归地获取所有目录,希望减少遍历驱动器所需的时间。下面是我尝试过的代码。本质上我想要做的是输入一个文件夹,并对其子文件夹及其子文件夹等并行执行相同的操作,但该函数在并行块内无法识别

function New-RecursiveDirectoryList {
    [CmdletBinding()]
    param (
        # Specifies a path to one or more locations.
        [Parameter(Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Path to one or more locations.')]
        [Alias('PSPath')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Path
    )
    process {
        foreach ($aPath in $Path) {
            Get-Item $aPath

            Get-ChildItem -Path $aPath -Directory |
                # Recursively call itself in Parallel block not working
                # Getting error "The term 'New-RecursiveDirectoryList' is not recognized as a name of a cmdlet"
                # Without -Parallel switch this works as expected
                ForEach-Object -Parallel {
                    $_ | New-RecursiveDirectoryList
                }
        }
    }
}

Error:

New-RecursiveDirectoryList: 
Line |
   2 |                      $_ | New-RecursiveDirectoryList
     |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The term 'New-RecursiveDirectoryList' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

我还尝试使用 mklement0 提供的解决方案here但没有运气。以下是我对此的尝试:

    function CustomFunction {
    [CmdletBinding()]
    param (
        # Specifies a path to one or more locations.
        [Parameter(Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Path to one or more locations.')]
        [Alias('PSPath')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Path
    )

    begin {
        # Get the function's definition *as a string*
        $funcDef = $function:CustomFunction.ToString()
    }

    process {
        foreach ($aPath in $Path) {
            Get-Item $aPath

            Get-ChildItem -Path $aPath -Directory |
                # Recursively call itself in Parallel block not working
                # Getting error "The term 'New-RecursiveDirectoryList' is not recognized as a name of a cmdlet"
                # Without -Parallel switch this works as expected
                ForEach-Object -Parallel {
                    $function:CustomFunction = $using:funcDef
                    $_ | CustomFuction
                }
        }
    }
}

Error

CustomFuction: 
Line |
   3 |                      $_ | CustomFuction
     |                           ~~~~~~~~~~~~~
     | The term 'CustomFuction' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

有谁知道如何实现这一点或以不同的方式实现这一点?


所以,这对我有用,但显然看起来不太漂亮。 需要注意的一件事是,foreach ($aPath in $Path) {...}在你的脚本上是不必要的,process {...}当您通过多个路径时,块会为您处理这个问题。

Code:

function Test {
    [CmdletBinding()]
    param (
        # Specifies a path to one or more locations.
        [Parameter(
            Mandatory,
            ParameterSetName = 'LiteralPath',
            ValueFromPipelineByPropertyName,
            Position = 0)]
        [Alias('PSPath')]
        [string[]] $LiteralPath
    )

    begin {
        $scriptblock = $MyInvocation.MyCommand.ScriptBlock.ToString()
    }

    process {
        # Get-Item $Path <= This will slow down the script
        $LiteralPath | Get-ChildItem -Directory | ForEach-Object -Parallel {
            $sb = $using:scriptblock
            $def = [scriptblock]::Create($sb)
            $_ # You can do this instead
            $_ | & $def
        }
    }
}

回顾这个答案,我今天建议的是不要使用递归并使用ConcurrentStack<T>相反,这会提高效率并消耗更少的内存。还值得注意的是,如马克门0在他的评论中指出,您的代码一开始是正确的,问题是由于拼写错误造成的:$_ | CustomFuction -> $_ | CustomFunction.

function Test {
    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'LiteralPath',
            ValueFromPipelineByPropertyName,
            Position = 0)]
        [Alias('PSPath')]
        [string[]] $LiteralPath,

        [Parameter()]
        [ValidateRange(1, 64)]
        [int] $ThrottleLimit = 5
    )

    begin {
        $stack = [System.Collections.Concurrent.ConcurrentStack[System.IO.DirectoryInfo]]::new()
        $dir = $null
    }

    process {
        $stack.PushRange($LiteralPath)
        while ($stack.TryPop([ref] $dir)) {
            $dir | Get-ChildItem -Directory | ForEach-Object -Parallel {
                $stack = $using:stack
                $stack.Push($_)
                $_
            } -ThrottleLimit $ThrottleLimit
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 ForEach-Object -Parallel 块内从自身递归调用函数 - 并行块内无法识别函数 的相关文章

  • PowerShell,使用 Start-Job 和 Start-Process 测试异步任务的性能/效率

    我很想测试 PowerShell 中异步任务的性能 有用性Start ThreadJob Start Job and Start Process 我有一个包含大约 100 个 zip 文件的文件夹 因此进行了以下测试 New Item 00
  • 如何使用 PowerShell 捕获全局击键?

    Powershell 可以监听并捕获按键吗 是否可以编写一个 PowerShell 脚本 例如自动热键 https www autohotkey com 位于托盘中并等待您按下预定义的键盘键才开始执行 并且每次按下所述键时可能不会返回而是触
  • PowerShell:使用 Invoke-Expression 管理错误

    我尝试弄清楚如何确定使用 Invoke Expression 的命令抛出是否失败 即使变量 LASTEXITCODE 或 ErrorVariable 也对我没有帮助 例如 PS C gt cmd cat c xxx txt 使用 Invok
  • 并行何时会提高性能

    我试图理解何时使用parallel会提高性能 我用一个简单的代码对其进行了测试 该代码运行了超过 100 000 个项目List
  • cURL 命令在 git bash 中有效,但在 cmd 和 powershell 中无效

    以下命令在 git bash 中有效 但在 cmd 和 powershell 中无效 curl X POST http localhost 5678 api findgen H Content Type application json d
  • 将服务器添加到 SQL Management Studio

    我想将不同服务器上的一堆 SQL 2000 2005 的混合 服务器实例添加到我的 SSMS SQL Managment Studio 注册服务器 我正在遵循本教程here http sev17 com 2008 12 registerin
  • Powershell 中的反斜杠

    为什么 split 参数的字符串需要两个反斜杠 而 join 参数的字符串只需要一个反斜杠 反引号是 Powershell 中的转义字符 字符前面的反斜杠有什么作用 path C folder test unit1 testing resu
  • 子进程调用,它们是并行完成的吗?

    我一直在谷歌搜索这个问题的答案 但似乎没有一个答案 谁能告诉我如果subprocess模块是否并行调用 Python 文档建议它可用于生成新进程 但没有提及它们是否并行 如果它们可以并行完成 您能否给我举一个例子或将我链接到一个例子 这取决
  • 替换第二个和第三个下划线之间的任何内容

    我有一个 PowerShell 脚本行 它用 替换 删除 第二个和第三个下划线之间的字符 get childitem pdf rename item newname name replace p L p L 例子 12345 00001 L
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • () 和 $() 之间的区别[重复]

    这个问题在这里已经有答案了 有什么区别 Write Host Get Date just paren and Write Host Get Date dollar paren 括号内的内容可以是任何内容 仅举一个简单的示例 两者有什么区别吗
  • PowerShell 中转义反引号“`”和反斜杠“\”有什么区别?

    我知道两者都在 PowerShell 中使用 但用于不同的上下文 互联网上关于这个主题的信息很少 唯一谈论这个主题的网站 没有让我理解这个概念 是 https www rlmueller net PowerShellEscape htm h
  • Parallel.ForEach - 优雅取消

    关于等待任务完成和线程同步的主题 我目前有一个迭代 我已将其包含在 Parallel ForEach 中 在下面的示例中 我在评论中提出了一些关于如何最好地处理循环的优雅终止的问题 NET 4 0 private void myFuncti
  • 具有多个参数和返回值的两个并行函数

    我有两个独立的功能 每一个都需要相当长的时间来执行 def function1 arg do some stuff here return result1 def function2 arg1 arg2 arg3 do some stuff
  • Powershell 数组到带引号的逗号分隔字符串

    我有一个数组 需要输出到逗号分隔的字符串 但我还需要引号 这是我所拥有的 myArray file1 csv file2 csv a myArray join a 输出为 a最终 file1 csv file2 csv 我想要的输出是 fi
  • PSExec 中的会话 ID

    Psexec 无法在远程会话上为我显示记事本 GUI 因此 我尝试获取会话 ID 如下所示 c Users Amitra Downloads PSTools gt PsExec u administrator p force 135 20
  • 如何获取管道对象的数量?我不想累积管道来缓冲

    假设我有一些 powershell 代码 function count pipe CmdletBinding param Parameter ValueFromPipeline true object inputObject process
  • 如何从 PowerShell 指定应用程序池身份用户和密码

    我在自动化 Web 应用程序设置和使用应用程序池标识适当配置 IIS 方面遇到了很多困难 我在用 PowerShell 编写的 Web 应用程序部署脚本中执行此操作 我的要求是我需要 PowerShell 脚本将应用程序池身份用户设置为特定
  • Powershell 查询的升序和降序

    下面的查询将列出 powershell 中的 cmdlet get command CommandType cmdlet Group Object Property verb 因为我需要按降序对列数进行排序 然后按升序对列进行命名 以下查询
  • 使用 powershell 编辑 XML

    好吧 我感觉自己像个大白痴 为了工作中的管理目的 我使用 Powershell 已经有一段时间了 也就是说 编写脚本不是我的强项 现在 我正在尝试编写一个 PS 脚本 将一个部分添加到一堆机器上的 XML 中 以添加设置来解决我们在某个应用

随机推荐

  • 在 Flask 中为 url_for 创建动态参数

    我有一个 jinja2 模板 我将其重复用于不同的 Flask 路由 所有这些路由都有一个必需参数并且仅处理GET请求 但某些路由可能有额外的参数 有没有办法附加额外的参数url for 就像是 url for my custom url
  • Flutter:在恢复时更新小部件?

    在 Flutter 中 有没有办法在用户离开应用程序并立即返回时更新小部件 我的应用程序是基于时间的 尽快更新时间会很有帮助 您可以通过执行以下操作来监听生命周期事件 import package flutter material dart
  • CSRF 状态令牌与提供的状态令牌不匹配[重复]

    这个问题在这里已经有答案了 我知道 stackoverflow 上有大量关于 CSRF 状态令牌与提供的令牌不匹配 问题的帖子 但是 我尝试过 似乎没有解决问题 你能看一下我下面的代码吗 请告诉我你的想法以及如何解决这个问题 我已经更新到最
  • WPF 保留 Tab 控件状态

    我已阅读帖子 如何停止 Wpf Tabcontrol 以在选项卡更改时卸载可视化树 但我无法让它工作 我一定错过了一些东西 请帮忙 谢谢 我正在使用示例项目 中的TabControlEx类http www pluralsight train
  • C++ EOF 运行太多次?

    这是我第一次使用 EOF 和 或文件 我遇到了代码挂起的问题 我相信这是因为我的 EOF 循环次数太多 我从文件中进行输入 并以这种方式动态创建对象 一旦文件运行完毕 它就会挂起 while studentFile eof cout lt
  • 如何使用 Alpha 通道为 png 图像着色?

    我正在尝试编写典型的 DVD 弹跳屏幕保护程序 我对此很满意 但我想在每次它撞到墙上时改变标志的颜色 我使用了 fill 但徽标变为彩色矩形 我想更改徽标的颜色 尊重图像的 Alpha 通道 from pygame import impor
  • 我的 Hive 客户端停止使用 Cosmos 实例

    我有一个 Hive 客户端 用 Java 编写 它与 FIWARE 实验室的 Cosmos 全局实例配合得很好 但是 它不再工作了 客户端似乎无法连接 超时 服务器端有什么变化吗 这是因为 FIWARE Lab 的 Cosmos 全局实例已
  • Kotlin 匿名函数用例?

    根据我的理解 Kotlin 中的匿名函数允许您指定返回类型 除此之外 anonymous 中的 return 语句将仅退出函数块 而在 lambda 中它将退出封闭函数 不过 我无法想象 lambda 语法无法提供的 Kotlin 中匿名函
  • 求VCL工具栏布局图设计

    我正在寻找 C 构建器的 VCL 组件 它最好有一个具有拖放功能的工具栏 我想定义一个建筑物或区域 可能不是矩形 并将其分成 房间 或区域 或任何你想称呼它们的东西 我希望能够将 门口 或通道等 从一个房间放入其邻居中 有这样的事吗 最好是
  • 使用 Python 将 Pandas DataFrame 导出为 PDF 文件

    在 Pandas 中为数据框生成 PDF 的有效方法是什么 第一个绘图表matplotlib然后生成pdf import pandas as pd import numpy as np import matplotlib pyplot as
  • HTML WebSocket 是否为每个客户端维护一个开放连接?这个有规模吗?

    我很好奇是否有人有关于 HTML WebSockets 可扩展性的任何信息 对于我读到的所有内容 似乎每个客户端都会与服务器保持开放的通信线路 我只是想知道它是如何扩展的以及服务器可以处理多少个打开的 WebSocket 连接 也许让这些连
  • Java 中如何找到给定类的所有子类?

    在 Java 中 如何尝试查找给定类的所有子类 或给定接口的所有实现者 到目前为止 我有一种方法可以做到这一点 但我发现它效率很低 至少可以说 方法是 获取类路径上存在的所有类名的列表 加载每个类并测试它是否是所需类或接口的子类或实现者 在
  • 不使用 gethostbyname 从 DNS 获取 IP?

    PHP s 获取主机名 就超时而言 函数似乎不可配置 我想将 DNS 请求限制为 1 秒或更短 因为再多的请求就会显示问题并应被忽略 那么 有没有一种方法可以使用套接字或 cURL 来进行 DNS 查询呢 我能够使用 PHP 流发出 SMT
  • 如何恢复 JavaFX TableColumn 的 onEditCommit 中的先前值?

    我有一个用 JavaFX 编写的表 用户可以选择编辑其中一列 当对单元格进行编辑时 我尝试根据新文本重命名一些内部对象 如果重命名失败 我会发出通知并弹出错误对话框 然后我想将原始文本恢复到该字段中 由于某种原因 这让我陷入了错误弹出窗口的
  • 在 bash 脚本中使用“备用屏幕”

    The 备用屏幕被许多 用户交互 终端应用程序使用 如 vim htop screen alsamixer less 它就像终端内容的不同缓冲区 当应用程序退出时它会消失 因此整个终端会恢复并看起来应用程序没有输出任何内容 我想在我自己的
  • REST - HTTP 状态 405 - 不允许的方法

    我尝试在我的网络项目上使用 REST POST 有效 但 DELETE 和 PUT 不起作用 我会看到错误 HTTP 状态 405 不允许方法 并且 GET 根本不起作用 id RFC 2068 中未定义 且 Servlet API 不支持
  • C# .Net 中 XmlElement 中的空白

    XmlElement child doc CreateElement element Where doc是一个对象XmlDocument 当代码执行上面一行时element Tom and Jerry 我收到以下错误 The charact
  • Woocommerce 中的本地取货运输选项自定义百分比折扣

    我的 WooCommerce 结帐页面提供了一些运输选项 统一费率 需要花钱 本地取货 免费 如果客户选择本地取货运输方式 我如何才能获得订单总成本 5 的折扣 以下代码将为购物车小计添加 5 的折扣当地取货选择的运输方式 add acti
  • UWP 中的 Process.Start

    我想从我的 UWP 应用程序运行文件 视频 音乐 图片 对于 WPF 我可以使用Process Start path 方法 但此方法现在可用于 UWP 我发现我可能应该使用FullTrustProcessLauncher https lea
  • 在 ForEach-Object -Parallel 块内从自身递归调用函数 - 并行块内无法识别函数

    第一次在这里提问 请善待 我试图以并行方式递归地获取所有目录 希望减少遍历驱动器所需的时间 下面是我尝试过的代码 本质上我想要做的是输入一个文件夹 并对其子文件夹及其子文件夹等并行执行相同的操作 但该函数在并行块内无法识别 function