2017-08-08 12 views
0

テキストファイル($ servers)で定義されたすべてのサーバ上でテキストファイル($ appname)で定義されたプログラムをアンインストールするための基本的なPSスクリプトを作成しました。サーバリストから複数のプログラムをアンインストールするPowerShellスクリプト

このコマンドを変数なしで手動で実行すると、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のを| ?{_。Name -eq "Microsoft Word"}

Microsoft Wordは、例です。 Mattsに従うことを簡単にされている必要があります

+0

正確に「うまくいく」ことを明確にするために質問を編集します。「変数は手動で実行していますか?あなたはあなたのワークステーションからそれを実行していますか? JenkinsとPSコマンドラインはあなたのワークステーションにありますか、それとも別のマシンにありますか? –

+0

こんにちはマイク、申し訳ありませんが私の編集@ MikeSherrill'CatRecall ' – jto

+0

を参照してくださいあなたが現在どの製品をアンインストールしているかを示す行を追加することができますそれはそこにトレンドがあるかどうかを確認するには、 '$ appname'は配列です。 '-eq'はそのような配列演算子ではありません。 '-contains'や' -in'のようなものを使う必要があります。また、すべての配列項目に対して '.Uninstall()'をすぐに呼び出すことができるかどうかわかりません。 '$ appname-contains $ _。name'または' $ appname'には1行しかありませんか? – Matt

答えて

0

あなたは2つの配列の比較を行っている

[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() 
} 
+0

こんにちは、私はマットのヒントに従っていますが、それはまだ動作しません、私は恐れています。 – jto

+0

しかし、次のエラーメッセージが表示されます。ヌル値の式でメソッドを呼び出すことはできません。 Dで :\ジェンキンス\ BuildUtilitiesのCitrix \ UninstallPrograms.ps1 \:6文字:5 + $ prod.uninstall() + ~~~~~~~~~~~~~~~~~ + CategoryInfo: InvalidOperation:(:) []、RuntimeException + FullyQualifiedErrorId:InvokeMethodOnNull – jto

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秒かかった。テスト:

+1

devmodeの代わりに、 'write-debug'を使うことができます。また、あなたは 'Verbonse' =>' verbose'のスペルミスを持っています – Matt

+0

@Mattありがとう、それは素晴らしい考えです。 – Paolis

+0

こんにちは@Paolisは答えに時間を割いてくれてありがとう。私は現在Jenkinsであなたのスクリプトを試していますが、10分間稼働していますが、インストールされているすべてのアプリケーションをサーバーにインストールしていないのですが、これを行うより効率的な方法はありますか? $ appnameにリストされているアプリケーションを探しているだけかもしれませんか? – jto

関連する問題