Chocolatey パッケージをリモートに展開するための「無料の」ソリューションの1つに、PowerShell があります。PowerShell には、ソフトウェアを多数の異なるマシンに同時に展開できるリモート処理機能があります。このブログではその使い方を説明します。
以前のブログにも書きましたが、Chocolatey は組織内でソフトウェアを管理するためのユニバーサルな方法を提供するので、多くの Windows システム管理者に歓迎されています。Chocolatey とCMD や PowerShell との間のインタフェースとして CLI(コマンドラインインタフェース)が使用されることからもわかるように、ソフトウェアをクライアントのワークステーションやサーバーにリモート展開するには、PowerShell 以外にも、Puppet、Chef、SCCM など、別の方法を使うことも可能です。
PowerShell のリモート処理の例
筆者自身が重宝してよく使うコマンドは、Invoke-Command です。このコマンドレットを使って、多くのコンピュータ上で同時にリモートコマンドやスクリプトを実行できます。よく使われるパラメータは、ComputerName と ScriptBlock の2つです。ComputerName パラメータには、リモートコードを実行するホスト名を指定します。ホストは1つでも複数でも指定できます。ScriptBlock パラメータは、その名が示す通り、実行したいコードのブロックです。
次は、Active Directory にあるすべてのマシンの User Profile Service のステータスを取得する例です。
$Computers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
Invoke-Command -ComputerName $Computers -ScriptBlock {
if (Get-Service ProfSvc | Where-Object {$_.Status -eq 'Running'}) {
Write-Output "$Env:COMPUTERNAME has ProfSvc running"
}
}
PowerShell は、User Profile Service が稼働中であるかどうかをチェックし、稼働中のコンピュータ名をアウトプットとして返します。
WIN-1 has ProfSvc running
WIN-2 has ProfSvc running
WIN-3 has ProfSvc running
WIN-4 has ProfSvc running
Chocolatey のインストール
Chocolatey パッケージをインストールするためには、ローカルマシン上であろうと、リモートの PowerShell セッション上での実行であろうと、同じ choco install コマンドを使用します。プロンプトを表示せずにパッケージをインストールするには、-y 引数を追加します。
ローカルマシンに Firefox をインストールするには次のようにします。
choco install firefox –y
これだけで、Firefox はインストールされて使用できるようになります。一度に複数のパッケージをインストールすることも簡単です。ただ、choco install コマンドの後に、複数のパッケージ名をスペースで区切って指定するだけです。
choco install firefox googlechrome -y
複数マシンへのリモートインストール
このセクションでは、複数のマシンに一度に Google Chrome をインストールする方法を説明します。まず、Active Directory で特定のOU(Windows 10)を検索して、コンピュータ名を PowerShell の変数にロードします。次に、Invoke-Command を使用してそれぞれのマシンに choco install を適用します。Chocolatey が Chrome を正常にインストールしたかどうかを確認するエラーチェックも行います。
$Computers = Get-ADComputer -Filter * -SearchBase "OU=Windows 10,DC=domain,DC=com" | Select-Object -ExpandProperty Name
Invoke-Command -ComputerName $Computers -ScriptBlock {
choco install googlechrome -y | Out-File -FilePath C:\Windows\Temp\choco-googlechrome.txt
if ($?) {
Write-Output "$Env:COMPUTERNAME Successful"
}
else {
Write-Output "$Env:COMPUTERNAME Failed"
}
}
アウトプットは、例えば以下のように返ってきます。
WIN10-1 Successful
WIN10-2 Failed
PowerShell で $? 変数を使用すると、各マシンで前のコマンドが成功したかどうかをチェックすることができます。ここでは choco install のアウトプットを C:\Windows\Temp のログファイルにリダイレクトしています。アウトプットをリダイレクトしないと、すべてがローカルの PowerShell セッションに返されてしまうため、解読するのが非常に困難になるからです。また、必要が生じたとき、個々のログを詳細に調べるのが少し楽になります。
複数マシンのすべての Chocolatey ソフトウェアをリモートでアップグレード
最後に、メンテナンス期間中に、複数のマシンで使用されているすべての Chocolatey パッケージをアップグレードする方法を説明します。この場合も、PowerShell の Invoke-Command を使用しますが、今回は各マシンのすべてのパッケージをアップグレードします。エラーチェックを念入りにしないといけないので、choco upgrade all は使いません。その代わりに choco upgrade で個々のパッケージを個別に実行し、うまくいかなかったものがあればそのパッケージを PowerShell のハッシュテーブルに入れます。
$Computers = Get-ADComputer -Filter * -SearchBase "OU=Windows 10,DC=domain,DC=com" | Select-Object -ExpandProperty Name
Invoke-Command -ComputerName $Computers -ScriptBlock {
$Packages = choco list -lo -r | % {($_.split("|"))[0]}
foreach ($Package in $Packages) {
choco upgrade $Package -y | Out-File -FilePath "c:\Windows\Temp\choco-$Package.txt"
if ($LASTEXITCODE -ne '0') {
$Results = [PSCustomObject]@{
ComputerName = $Env:COMPUTERNAME
Package = $Package
}
$Results
}
}
} | Select-Object ComputerName,Package | Sort-Object -Property ComputerName
結果は、アップグレードしようとしている間にエラーがあったマシンとそのパッケージのソートされたリストになります。
ComputerName Package
------------ -------
WIN10-1 vagrant
WIN10-1 Gpg4win
WIN10-1 bitvise-ssh-client
WIN10-1 citrix-receiver
WIN10-2 dropbox
まとめ
ソフトウェアを展開するには多くのツールがありますが、PowerShell のリモート処理も検討に値するオプションです。インテリジェントなスクリプトを組み合わせて、一度に多くのマシンにパッケージをインストールしたり、アップグレードしたりでき、効率化が実現できます。
Dan Franciscus
Dan Franciscus is a systems engineer and VMware Certified Professional (VCP) specializing in VMware, PowerShell, and other Microsoft-based technologies. You can reach Dan at his blog (http://www.winsysblog.com/) or Twitter at @dan_franciscus.