PowerShell 慢调用命令
PowerShell slow Invoke-Command
我正在编写一个 PowerShell 脚本,它从所有 AD 服务器读取所有共享并将它们输出到一个 csv 文件中。同时,脚本会保存所有发生的错误并将它们输出到错误日志中。你们能不能看出有什么可能可以加快整个过程,因为现在需要相当长的时间。
我的代码:
function output1 {
Get-Content C:\PowerShell\Shares\serverlist.txt | Where-Object { $_.name -like "*" } | ForEach-Object {
$ErrorActionPreference = 'silentlycontinue'
$name = $_ + ".domain.com"
$pathnotnull = $_.Path -ne ""
invoke-command -ComputerName $name -ArgumentList $name, $pathnotnull -ScriptBlock {
param($name, $pathnotnull)
Get-SmbShare | where-object { $_.Path -ne '' } | Select-Object -Property "Name", "Path" | get-acl | Select-Object -Property "PSChildName", "Path", "Group", "AccessToString"
}
if (!$?) {
if ($error[0].exception.message) { Write-Host "Access to $_ failed!" -ForegroundColor Red }
$error | Set-Content $error_logfile -Encoding Unicode
}
else {
Write-Host "Access to $_ successful!" -ForegroundColor Green
return $i
}
}
}
$i = output1
$i | Out-Null
$ErrorActionPreference = 'silentlycontinue'
if ($i -ne $null) {
$i | export-csv -path C:\PowerShell\Shares\shares.csv -NoTypeInformation -delimiter ";"
}
else {
""
write-host "No server could be contacted!" -ForegroundColor Red
""
openerrorlog1
}
我相信您的代码可以简化为这样,因为 mklement0 suggests、Invoke-Command
可以采用一组计算机并并行调用相同的脚本块,这将使您的脚本 运行 呈指数级增长。在这种情况下,我也不认为需要 函数 。至于从 Invoke-Command
捕获错误,您可以将它们重定向 (2>&1
) 到成功流,然后您可以按 -is [ErrorRecord]
:
进行过滤
$ErrorActionPreference = 'Continue'
$computers = (Get-Content C:\PowerShell\Shares\serverlist.txt).ForEach({
if(-not [string]::IsNullOrWhiteSpace($_))
{
"$_.domain.com"
}
})
$remoteCode = {
Get-SmbShare | Where-Object Path | Get-Acl |
Select-Object -Property "PSChildName", "Path", "Group", "AccessToString"
}
$results = Invoke-Command -ComputerName $computers -ScriptBlock $remoteCode 2>&1
$errors, $good = $results.Where({$_ -is [System.Management.Automation.ErrorRecord]}, 'Split')
$good | Export-Csv .....
# Here are the Errros
$errors.Exception.Message
我正在编写一个 PowerShell 脚本,它从所有 AD 服务器读取所有共享并将它们输出到一个 csv 文件中。同时,脚本会保存所有发生的错误并将它们输出到错误日志中。你们能不能看出有什么可能可以加快整个过程,因为现在需要相当长的时间。
我的代码:
function output1 {
Get-Content C:\PowerShell\Shares\serverlist.txt | Where-Object { $_.name -like "*" } | ForEach-Object {
$ErrorActionPreference = 'silentlycontinue'
$name = $_ + ".domain.com"
$pathnotnull = $_.Path -ne ""
invoke-command -ComputerName $name -ArgumentList $name, $pathnotnull -ScriptBlock {
param($name, $pathnotnull)
Get-SmbShare | where-object { $_.Path -ne '' } | Select-Object -Property "Name", "Path" | get-acl | Select-Object -Property "PSChildName", "Path", "Group", "AccessToString"
}
if (!$?) {
if ($error[0].exception.message) { Write-Host "Access to $_ failed!" -ForegroundColor Red }
$error | Set-Content $error_logfile -Encoding Unicode
}
else {
Write-Host "Access to $_ successful!" -ForegroundColor Green
return $i
}
}
}
$i = output1
$i | Out-Null
$ErrorActionPreference = 'silentlycontinue'
if ($i -ne $null) {
$i | export-csv -path C:\PowerShell\Shares\shares.csv -NoTypeInformation -delimiter ";"
}
else {
""
write-host "No server could be contacted!" -ForegroundColor Red
""
openerrorlog1
}
我相信您的代码可以简化为这样,因为 mklement0 suggests、Invoke-Command
可以采用一组计算机并并行调用相同的脚本块,这将使您的脚本 运行 呈指数级增长。在这种情况下,我也不认为需要 函数 。至于从 Invoke-Command
捕获错误,您可以将它们重定向 (2>&1
) 到成功流,然后您可以按 -is [ErrorRecord]
:
$ErrorActionPreference = 'Continue'
$computers = (Get-Content C:\PowerShell\Shares\serverlist.txt).ForEach({
if(-not [string]::IsNullOrWhiteSpace($_))
{
"$_.domain.com"
}
})
$remoteCode = {
Get-SmbShare | Where-Object Path | Get-Acl |
Select-Object -Property "PSChildName", "Path", "Group", "AccessToString"
}
$results = Invoke-Command -ComputerName $computers -ScriptBlock $remoteCode 2>&1
$errors, $good = $results.Where({$_ -is [System.Management.Automation.ErrorRecord]}, 'Split')
$good | Export-Csv .....
# Here are the Errros
$errors.Exception.Message