powershell - 加快我的 PowerShell 脚本的处理速度

标签 powershell csv

如何加快 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/

相关文章:

python - 使用 CSV : reading and writing data in the right order

python - python 中的数据类型(寻找类似于 R 中的 str 的东西)

java - 尽可能快地通过java读取具有数百万行的csv文件

powershell - 获取命令 : One command - two usage scenarios - unexpectedly two very different outcomes

PowerShell 和 ActiveDirectory 模块 - 查找不是特定组成员的用户

powershell - 从 cygwin 运行时如何结束 s Powershell 脚本

java - 如何处理 Spark rdd 生成上的 CSV 文件列?

powershell - 使用powershell命令批处理脚本检查文件夹大小

powershell - 我想通过命令行使用自定义帐户验证应用程序池身份

python - df = pd.read_csv ('iris.csv' ) 指向 azure blob 报告中的文件 [errno 2] 没有这样的文件或目录