我编写了一个基本的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就是一个例子。
答案 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