如何加快 PowerShell 脚本的处理速度?
它从 apps.csv 文件(包含 2 个应用程序 - Windows XP 和 Windows 7 版本)和 hosts.csv 文件中提取信息。
应用程序位置在不同的主机名上进行测试(我可以判断它们是否是 Windows XP/Windows 7 机器),以通过检查指纹来查看它们是否已安装。
目前运行40+条记录大约需要5-10分钟,确实需要加快速度。
clear all
$Applications = @{}
$ComputerObjects = @()
# Gets OS
function Get-OS ([string]$hostname) {
$os = "offline"
gwmi win32_operatingsystem -computername $hostname -ea silentlycontinue | ForEach-Object {
if($_.Version.ToString().StartsWith("6.1")) {
$os = "Windows 7"
} elseif ($_.Version.ToString().StartsWith("5.1")){
$os = "Windows XP"
} else {
$os = "N/A"
}
} > $null
return $os
}
# Sorts out the application information, breaking it into OS, LOB and then finally Location
Import-CSV C:\RDC\apps.csv | ForEach-Object {
$appname = $_.appname.ToLower()
$os = $_.os.ToLower()
$lob = $_.lob.ToLower()
$location = $_.location.ToLower()
if ($Applications.Keys -notcontains $appname) {
$WindowsOS=@{}
# hashtable for windows xp and windows 7 applications
$WindowsOS["windows xp"]=@{}
$WindowsOS["windows 7"]=@{}
$Applications[$appname]=$WindowsOS
}
if ($Applications[$appname][$os].Keys -notcontains $lob) {
$Applications[$appname][$os][$lob]=@()
}
if ($Applications[$appname][$os][$lob].Keys -notcontains $location) {
$Applications[$appname][$os][$lob]+=$location
}
}
# Sorts the Hostnames out and tests all Application Locations
Import-CSV C:\RDC\hosts.csv | ForEach-Object {
$Properties = @{}
$Properties["hostname"]=$_.hostname.ToLower()
$Properties["lob"]=$_.type.ToLower()
$Properties["os"]=Get-OS $Properties["hostname"]
$Applications.Keys | ForEach-Object {
$currAppName = $_
$Properties[$currAppName]=$false;
if ($Applications[$currAppName].Keys -contains $Properties["os"] -and $Applications[$currAppName][$Properties["os"]].Keys -contains $Properties["lob"]) {
$Applications[$currAppName][$Properties["os"]][$Properties["lob"]] | ForEach-Object {
$Properties[$currAppName]=$Properties[$currAppName] -or (Test-Path "\\$($Properties["hostname"])\$($_)")
}
}
}
$HostObject = New-Object PSObject -Property $Properties
$ComputerObjects += $HostObject
}
$ComputerObjects | ft
$a = [int][double]::Parse((Get-Date -UFormat %s))
#$ComputerObjects | Export-csv "C:\Working\results_$a.csv" -NoTypeInformation
最佳答案
这是一个使用作业的例子:
param( $computername=$fullnameRODC)
Invoke-Command -ComputerName $computername -AsJob -JobName checkOS -ScriptBlock {
$o=@{}
$os = "offline"
gwmi win32_operatingsystem -ea silentlycontinue | ForEach-Object {
if($_.Version.ToString().StartsWith("6.1")) {
$os = "Windows 7"
} elseif ($_.Version.ToString().StartsWith("5.1")){
$os = "Windows XP"
} else {
$os = "N/A"
}
}
$o["os"]=$os
$r=new-Object -TypeName psObject -Property $o
$r
}
wait-Job checkOS
receive-Job checkOS
remove-job checkOS
使用 Measure-Command -Expression {c:\temp\cheskOS.ps1}
这个脚本在大约 10 秒内执行。
没有工作
param( $computername=$fullnameRODC)
gwmi win32_operatingsystem -computername $computername -ea silentlycontinue | ForEach-Object {
if($_.Version.ToString().StartsWith("6.1")) {
$os = "Windows 7"
} elseif ($_.Version.ToString().StartsWith("5.1")){
$os = "Windows XP"
} else {
$os = "N/A"
}
}
$os
需要 4 分钟,慢 24 倍!
更新您的脚本。我认为最简单的事情是使用作业来检查操作系统并将结果存储到数组中。然后替换你的 get-os 函数。那就是:
param( $computername=@("computer1","computer2"))
$results=@()
Invoke-Command -ComputerName $computername -AsJob -JobName checkOS -ScriptBlock {
$o=@{}
$os = "offline"
gwmi win32_operatingsystem -ea silentlycontinue | ForEach-Object {
if($_.Version.ToString().StartsWith("6.1")) {
$os = "Windows 7"
} elseif ($_.Version.ToString().StartsWith("5.1")){
$os = "Windows XP"
} else {
$os = "N/A"
}
}
$o["os"]=$os
$r=new-Object -TypeName psObject -Property $o
$r
}
wait-Job checkOS
$results+=receive-Job checkOS
remove-job checkOS
function Get-OS ([string]$computername) {
$script:results | ?{$_.pscomputername -eq $computername} | select os
}
然后你可以做
get-os "computer2"
关于powershell - 加快我的 PowerShell 脚本的处理速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21473443/