我有一个脚本,可以将 CAB 文件复制到一百多个服务器上,并在它们上使用。该脚本运行了一个多星期。当我了解 Foreach-Object 并行功能时,我认为这会大大加快脚本速度。但我遇到了一个问题。由于我不太了解 PowerShell,而且我在任何地方都没有找到有关此问题的帖子,所以我想,我要碰碰运气,并在这里提问:
我想将变量传递给 foreach-object cmdlet 中执行的脚本块,如下所示:
$test = "123"
1..3|foreach-object -parallel {param($test);echo "$_, $test"} -ArgumentList($test)
Run Code Online (Sandbox Code Playgroud)
我的期望:
1, 123
2, 123
3, 123
Run Code Online (Sandbox Code Playgroud)
我得到什么:
ForEach-Object:无法使用指定的命名参数解析参数集。发出的一个或多个参数不能一起使用或提供的参数数量不足。
我究竟做错了什么?
这可能是一个微不足道的问题。但因为我没有到达任何地方,也没有找到任何帖子/代码示例。我把它发布在这里。我很感谢您的回答。
我是 powershell 的新手,刚刚学习它。我有一些 C# 经验。我正在尝试使用 foreach-object -Parallel 选项,但无法让所有 Write-* 函数正常工作。
function writeTest {
1..1 | ForEach-Object -Parallel {
Write-Host "host"
Write-Output "Output"
Write-Information "information" -InformationAction Continue
Write-Verbose "verbose"
Write-Warning "Warning"
Write-Error "error"
}
}
Run Code Online (Sandbox Code Playgroud)
函数调用如下:writeTest -verbose
输出:
host
Output
WARNING: Warning
Write-Error: error
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么 write-verbose 和 write-information 不显示任何内容?
如有无知之处请原谅。
parallel-processing powershell output foreach-object powershell-7.0
我对 ForEach-Object -Parallel 感到困惑。以下代码有包含超过 2000 个 blob 的 $blobs 数组。使用常规的foreach,我可以毫无问题地打印每个 blob 的名称。然后在第一个 foreach 之后使用ForEach-Object -Parallel ,不会打印任何内容。为什么 ?
foreach ($blob in $blobs) {
Write-Host $blob.Name
}
# Use parallel processing to process blobs concurrently
$blobs|ForEach-Object -Parallel {
param (
$blob)
Write-Host $blob.Name
} -ThrottleLimit 300
Run Code Online (Sandbox Code Playgroud) parallel-processing powershell azure-blob-storage foreach-object
第一次在这里提问。请善待:)
我试图以并行方式递归地获取所有目录,希望减少遍历驱动器所需的时间。下面是我尝试过的代码。本质上我想要做的是输入一个文件夹并对其子文件夹及其子文件夹等并行执行相同的操作,但该函数在并行块内无法识别
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" …Run Code Online (Sandbox Code Playgroud) 此代码打印一个简单的进程,一次只做一件事:
$files = 1..100
$i = 0
$files | Foreach-Object {
$progress = ("#" * $i)
Write-Host "`r$progress" -NoNewLine
$i ++
Start-Sleep -s 0.1
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我想同时并行执行两件事,我无法输出进度,因为我无法更改并行循环之外的变量。这并没有完成所需的操作:
$files = 1..100
$i = 0
$files | Foreach-Object -ThrottleLimit 2 -Parallel {
$progress = ("#" * $i)
Write-Host "`r$progress" -NoNewLine
$i ++
Start-Sleep -s 0.1
}
Run Code Online (Sandbox Code Playgroud)
我找不到一个好的解决方案来访问外部变量,不仅可以使用 $Using 读取它,还可以更改它。这在 Powershell 7 中可能吗?
我正在尝试使用 ForEach-Object -Parallel 从多个服务器收集数据。我使用的变量正在循环内填充,但是当循环完成时该变量为空。
$DBDetails = "SELECT @@VERSION"
$VMs = ("vm1", "vm2", "vm3", "vm4", "vm5", "vm6", "vm7")
$DBInventory = @()
$scriptBlock = {
$vm = $_
$result = Invoke-Sqlcmd -ServerInstance $vm -Query $using:DBDetails
$DBInventory += $result
Write-Host "Added $($result.Count) rows from $($vm)"
}
$VMs | ForEach-Object -Parallel $scriptBlock
Write-Host "Number of elements in DBInventory: $($DBInventory.Count)"
Run Code Online (Sandbox Code Playgroud)
我希望最后一行返回在前一行执行的循环中收集的元素数量。总共应该有 7 个元素,但我一个都没有。
我的结果如下所示:
Added 1 rows from vm1
Added 1 rows from vm2
Added 1 rows from vm3
Added 1 rows from vm4
Added …Run Code Online (Sandbox Code Playgroud) 我准备了这个脚本来尝试使用不同的参数多次并行执行相同的函数:
$myparams = "A", "B","C", "D"
$doPlan = {
Param([string] $myparam)
echo "print $myparam"
# MakeARestCall is a function calling a web service
MakeARestCall -myparam $myparam
echo "done"
}
$myparams | Foreach-Object {
Start-Job -ScriptBlock $doPlan -ArgumentList $_
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,输出是
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
79 Job79 BackgroundJob Running True localhost ...
81 Job81 BackgroundJob Running True localhost ...
83 Job83 BackgroundJob Running True localhost ...
85 Job85 BackgroundJob Running True …Run Code Online (Sandbox Code Playgroud) 在PowerShell中工作时,我需要将CIDR表示法转换为IP起始地址和子网掩码表示法.
执行谷歌搜索我发现这个Reddit发布挑战包含许多模糊的方法来执行此任务.
我觉得特别有趣的一个是:
$C = 13
[ipaddress](4.GB-(4GB-shr$C))|% i*g
Run Code Online (Sandbox Code Playgroud)
我花了一段时间才发现这-shr$C只是PowerShell -shr操作符,在$C变量引用之前没有任何空格.
然后我需要搜索以找到它%的别名Foreach-Object.
只需查询[ipaddress](4.GB-(4GB-shr$C))我收到的价值:
Address : 63743
AddressFamily : InterNetwork
ScopeId :
IsIPv6Multicast : False
IsIPv6LinkLocal : False
IsIPv6SiteLocal : False
IsIPv6Teredo : False
IsIPv4MappedToIPv6 : False
IPAddressToString : 255.248.0.0
Run Code Online (Sandbox Code Playgroud)
这向我展示了IPAddress对象的属性.我需要的结果是IPAddressToString我可以通过使用%| IPAddressToString或以某种方式强制PowerShell将对象作为字符串发出来获得的属性.
因此,现在的问题是语法是什么% i*g意思?
什么是i和g我们进行乘法运算?
由于使用 -Recurse 标志时,Get-ChildItem 的 -Exclude 参数不会对子文件夹进行过滤,因此请参阅使用 get-childitem-exclude-parameter-in-powershell 中的其他无法排除目录的内容
但 -Exclude 参数可用于过滤掉根级别的文件夹
我写了自己的递归函数:
function Get-ChildItem-Recurse() {
[cmdletbinding()]
Param(
[parameter(ValueFromPipelineByPropertyName = $true)]
[alias('FullName')]
[string[]] $Path,
[string] $Filter,
[string[]] $Exclude,
[string[]] $Include,
[switch] $Recurse = $true,
[switch] $File = $false
)
Process {
ForEach ( $P in $Path ) {
Get-ChildItem -Path $P -Filter $Filter -Include $Include -Exclude $Exclude | ForEach-Object {
if ( -not ( $File -and $_.PSIsContainer ) ) {
$_
}
if ( $Recurse -and $_.PSIsContainer ) {
$_ …Run Code Online (Sandbox Code Playgroud) 我有一系列文件,它们都是从基本系统导出的(补救措施)。默认情况下,它们在文件名之前有 32 个字符的 ID 相关信息。我想把这些字符去掉。然而,这样做也会导致重复,所以我需要一种方法来重命名它们而不创建重复。
例子:
CWL000000004901-z2AF 工作日志01-RFP 2012 01 获奖推荐.pdf
CWL000000004716-z2AF 工作日志01-Computrace 2009 年 11 月.pdf
CWL000000006007-z2AF 工作日志01-Computrace 2009 年 11 月.pdf
(删除前面的字符后,后 2 个将相同)
$i = 1
Get-ChildItem -Path "C:\temp\Remedy Contract Attachments\Output\CTR_WorkLog_test1_a" |
ForEach-Object -Process {
$NewName = $_.BaseName.Substring(32)
$NewName2 = $NewName + "_" + $i + $_.Extension
Rename-Item $_.FullName -NewName $NewName2
$i++
}
Run Code Online (Sandbox Code Playgroud)
这是我目前的代码。
似乎只要总字符数小于 64 就可以,
Computrace_Nov_2009_156.pdf
Computrace_Nov_2009_157.pdf
但随后它似乎会重复处理其余部分,就像这样
ietor_127_502.pdf
该文件夹中只有 394 个文件。
我从 PowerShell 学到的大部分内容都是从这里学到的,但我绝对被难住了。为什么它要多次处理文件?它会抛出一堆错误,表示它无法删除超过字符串中的字符数,因此显然它在最终崩溃之前仍在处理它们。但为什么?
或者有更好的方法来做到这一点吗?
我确信这是一件小事,我会因为整个下午都在与这些代码战斗而感到愚蠢。
谢谢!
我有这个代码:
Get-ChildItem FOLDERNAMEHERE *.png| ForEach-Object { $_.Name } > fileNames.txt
它打印出文件名列表,我想将其更改为仅打印数字索引而不是名称。
foreach-object ×11
powershell ×11
copy-item ×1
foreach ×1
indexing ×1
output ×1
pipeline ×1
start-job ×1