PowerShell脚本从服务器列表中卸载多个程序

时间:2017-08-08 10:44:33

标签: powershell variables text-files

我编写了一个基本的PS脚本,以便在文本文件($ servers)中定义的所有服务器上卸载文本文件($ appname)中定义的任何程序。

手动运行此命令没有变量它工作正常,但是通过Jenkins或PS命令行运行脚本它只是挂起所以我甚至无法调试,任何人都有任何想法?

[array]$servers= Get-Content "D:\Jenkins\BuildUtilities\Citrix\CitrixServerList.txt"
[array]$appname= Get-Content "D:\Jenkins\BuildUtilities\Citrix\ProgramsList.txt"

ForEach($server in $servers) { 

$prod=gwmi -ComputerName $server Win32_product | ?{$_.name -eq $appname}
$prod.uninstall()

}

澄清:手动运行我的意思是运行以下内容:     gwmi -ComputerName CTX-12 Win32_product | ?{_。名称-eq“Microsoft Word”}

Microsoft Word就是一个例子。

2 个答案:

答案 0 :(得分:0)

应该很容易遵循Matts提示

[array]$servers= Get-Content "D:\Jenkins\BuildUtilities\Citrix\CitrixServerList.txt"
[array]$appname= Get-Content "D:\Jenkins\BuildUtilities\Citrix\ProgramsList.txt"

ForEach($server in $servers) { 
    $prod=gwmi -ComputerName $server Win32_product | ?{ $appname -contains $_.name}
    $prod.uninstall()
}

答案 1 :(得分:0)

您正在对两个数组进行比较,您要做的是检查从服务器获取的prod数组中匹配应用程序的每个实例,因此使用管道的方式并不理想。

[array]$servers= Get-Content "D:\Jenkins\BuildUtilities\Citrix\CitrixServerList.txt"
[array]$appname= Get-Content "D:\Jenkins\BuildUtilities\Citrix\ProgramsList.txt"
$DebugPreference= 'Continue'

foreach($server in $servers) 
{ 
    Write-Debug "Getting all installed applications on server $server"
    $prod= Invoke-Command -ComputerName $server -Scriptblock {gwmi Win32_product}
    Write-Debug "Installed applications collected, there are $($prod.Count) items in the array."

    foreach($p in $prod)
    {
        Write-Debug "Searching apps array for the name $($p.Name)."
        if($appname -contains $p.Name)
        {
            Write-Verbose -Message "$($p.Name) found on server $server, uninstalling."
            $p.uninstall()
        }
        else
        {
            Write-Verbose -Message "$($p.Name) was not found on server $server."
        }
    }
}
编辑:由于你提出了速度问题,使用Win32_product非常慢。因此,更快的方法是从注册表项HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall获取已安装应用程序的列表(详细说明如何执行此操作here)。构建一个需要卸载的新应用程序阵列,然后调用Win32_product。只知道这只会加速脚本的一部分,如果找到任何应​​用程序,仍会发生减速。当您找到没有任何要卸载的应用程序的服务器时,主要的速度增益将来自。

EDIT2:使用简单的Invoke-Command进行了一些实验,大大加快了Get-WMIObject命令的速度。我在服务上做了它,单独使用命令花了9秒,使用Invoke-Command花了1秒钟。测试:

$firstStart = Get-Date
$service1 = Get-WmiObject win32_service -ComputerName $ServerName  
$firstEnd = Get-Date
$firstTime = New-TimeSpan -Start $firstStart -End $firstEnd 
Write-Host "The first collection completed in $($firstTime.TotalSeconds) seconds." -ForegroundColor Green

$secondStart = Get-Date
$service2 = Invoke-Command -ComputerName $ServerName -ScriptBlock {Get-WmiObject win32_service}
$secondEnd = Get-Date
$secondTime = New-TimeSpan -Start $secondStart -End $secondEnd 
Write-Host "The second collection completed in $($secondTime.TotalSeconds) seconds." -ForegroundColor Green