PowerShellからSCCMの更新を開始する

皆さん、更新プログラムの適用はどの様に実施されていますか?

直接Windows UpdateサイトやWSUSから更新する、必要な物を事前に配置しておいて手動でスクリプトでインストールするなど環境に応じて色々有るかと思いますが、SCCMから配信をされている管理者の方も多いかと思います。

SCCMから配信する場合、クライアントPCなどはある程度えいやでインストール期日を設定してしまっても良いのですが、適用順序などが決まっている場合に前のサーバ群が終わっているかのチェックをしてからインストールする必要があるなどの理由から、ソフトウェアセンターを開いて手動で適用を実施されているケースも多いのでは無いでしょうか。

大雑把な手順としては以下の様な物となります。

  1. 対象サーバにログイン
  2. ソフトウェアセンターを起動
  3. 左上のチェックボックス(全て)にチェック
  4. 右下の[インストール(N)]をクリック
  5. 失敗した物が有ったら再度チェックして実行
  6. 全部成功したら再起動

数十台のレンジであれば、Remote Desktop Connection Managerなどを利用して沢山リモートデスクトップのウィンドウを開いてポチポチしていけば何とかなるレベルですが、この方法のままでは数百台以上実施するのは難しいですよね。

今回は、この処理を簡略化していきたいと思います。メインとしては「スクリプトから実施」「リモートで実行」という2点となります。SCCMクライアントへは、WMIを使ってアクセスが可能ですので、PowerShellからこれをキックしたいと思います。

Get-SCCMUpdatesStatus

SCCMのソフトウェア更新プログラムの一覧と、現在のインストールの状態を表示する。
引数無しで実行した場合はローカルホストに対して実行、引数有りの場合はそのホストに対して実行する。

function Get-SCCMUpdatesStatus ($hostname){
  if($hostname -eq $NULL) { $hostname = hostname }
  $CCMUpdates = Get-WmiObject -Query "SELECT * FROM CCM_SoftwareUpdate" -Namespace "ROOT\ccm\ClientSDK" -Computer $hostname
  foreach ($CCMUpdate in $CCMUpdates) {
    if($CCMUpdate -eq $NULL) { "No SCCM updates are available for $hostname"}
    else {
      $Output = "Status: "
      $Output += $CCMUpdate.__SERVER
      $Output += " KB"
      $Output += $CCMUpdate.ArticleID
      $Output += " "
      switch($CCMUpdate.EvaluationState){
        0 {$Output += "Available"}
        1 {$Output += "Available"}
        5 {$Output += "Downloading"}
        6 {$Output += "Waiting to install"}
        7 {$Output += "Installing"}
        8 {$Output += "Requies restart"}
        10 {$Output += "Complete"}
        11 {$Output += "Pending Verification"}
        13 {$Output += "Failed"}
        default {$Output += "Unknown"}
      }
      $Output
    }
  }
}

Start-SCCMUpdates

SCCMのソフトウェア更新プログラムの全てをインストールする。
(既に開始済み、もしくは完了している更新プロぐむには影響を与えない。)
引数無しで実行した場合はローカルホストに対して実行、引数有りの場合はそのホストに対して実行する。

function Start-SCCMUpdates ($hostname){
  if($hostname -eq $NULL) { $hostname = hostname }
  $CCMUpdates = Get-WmiObject -Query "SELECT * FROM CCM_SoftwareUpdate" -Namespace "ROOT\ccm\ClientSDK" -Computer $hostname
  foreach ($CCMUpdate in $CCMUpdates) {
    if($CCMUpdate -eq $NULL) { "No SCCM updates are available for $hostname"}
    else {
      $Output = "Starting: "
      $Output += $CCMUpdate.__SERVER
      $Output += " KB"
      $Output += $CCMUpdate.ArticleID
      $Output += " (Status: "
      switch($CCMUpdate.EvaluationState){
        0 {$Output += "Available"}
        1 {$Output += "Available"}
        5 {$Output += "Downloading"}
        6 {$Output += "Waiting to install"}
        7 {$Output += "Installing"}
        8 {$Output += "Requies restart"}
        10 {$Output += "Complete"}
        11 {$Output += "Pending Verification"}
        13 {$Output += "Failed"}
        default {$Output += "Unknown"}
      }
      $Output += ")"
      $Output
      ([wmiclass]"\\${hostname}\ROOT\ccm\ClientSDK:CCM_SoftwareUpdatesManager").InstallUpdates($CCMUpdate) | Out-Null
    }
  }
}

この2つを使ってどこかのサーバから実施すればいいわけです。

例えば、server1,server3,server5に対して実行したい場合は、以下のような感じになります。

  1. foreach($hostname in @(“server1″,”server3″,”server5”)) { Start-SccmUpdates $hostname }
    を実行して、リモートでインストールを開始する。
  2. foreach($hostname in @(“server1″,”server3″,”server5”)) { Get-SccmUpdatesStatus $hostname }
    を実行して、全部Completeになるのを待つ。(失敗したサーバを見つけたらStart-SccmUpdates を再実行)
  3. foreach($hostname in @(“server1″,”server3″,”server5”)) { Restart-Computer -Force -ComputerName $hostname }
    を実行してリモートでインストール

実際の環境に合わせて、更新の前後にフェールオーバーなどの事前作業や再起動後の確認作業などの処理を足していけば良いという形になります。

良いSCCMライフを!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です