Home > Windows にまつわる e.t.c.

PowerShellでファイル配置


KB 等の適用で更新ファイルを対象サーバーに配置する必要がある時にどうしていますか?
リモートデスクトップ接続してコピペですか?

確かに、台数が少ないとその方法で問題ありませんが、対象が多い場合は大変ですね。

では、どうするか?
色々方法はありますが、僕が良く使う方法を紹介します。

 

PSDriveを使ってコピーする

ファイルサーバーの役割が有効になってる環境では、PSDrive を使ってターゲット サーバーの管理共有をマウントしてファイルをコピーします。

KB のインストールには管理権限が必要なので、管理権限を持ったアカウントを使います。
管理権限を持ったアカウントであれば、C$ 等の管理共有にアクセスできるので、管理共有を使って任意のフォルダーにファイルをコピーすることが可能です。

PSDrive の使い方は、New-PSDrive で管理共有を任意のドライブ名(この例では DriveC)にマウントし、ファイルをコピーした後に Remove-PSDrive でマウント解除します。
(認証は省略しているので、必要に応じて -Credential を使用してください)

PS C:\> New-PSDrive DriveC -PSProvider FileSystem -Root \\TergetServer\c$

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
DriveC                                 FileSystem    \\TergetServer\c$


PS C:\> $Terget = "DriveC:\InstallKB"
PS C:\> if( -not ( Test-Path $Terget )){ md $Terget }


    ディレクトリ: \\TergetServer\c$


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2015/04/19     15:47            InstallKB


PS C:\> copy C:\KB\Windows8.1-KB3042553-x64.msu $Terget -Force
PS C:\> Remove-PSDrive DriveC

 

net use を使って管理共有経由でファイルをコピーする

残念ながら PowerShell 2.0 以前の PSDrive では -PSProvider FileSystem で資格情報指定(-Credential)が機能しません。

こんな時は、net use コマンドを使います。

一般的に net use は共有に対してドライブレター割り当てをしますが、管理共有にアクセスするのであれば、ターゲットサーバーの指定だけでドライブレター割り当ては不要です。

このような使い方ができます。

PS C:\> net use \\TergetServer P@ssW0ord /user:HogeHoge
コマンドは正常に終了しました。

PS C:\> $Terget = "\\TergetServer\c$\InstallKB"
PS C:\> if( -not( Test-Path $Terget)){ md $Terget }


    ディレクトリ: \\TergetServer\c$


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2015/04/19     16:11            InstallKB


PS C:\> copy C:\KB\Windows8.1-KB3042553-x64.msu $Terget -Force
PS C:\> net use /delete \\TergetServer\IPC$ /yes
\\TergetServer\IPC$ が削除されました。

 

フィルサーバーからファイルを Pull させる

対象サーバーのファイルサーバー機能が有効になっているのなら、ファイルを Push する事が出来ますが、ファイルサーバー機能が無効な場合は、対象サーバーにファイルを Pull させるしかありません。

Pull させる時に活躍するのが Invoke-Command です。

PSDrive でもハンドリングできますが、ID パスワードがべた書きできる(説明が簡単にできる) net use を使ってファイルサーバーから対象サーバーの C:\InstallKB にファイルを pull copy させてみましょう。

Push の時の net use はドライブレター割り当て不要でしたが、Invoke-Command で Pull する場合はドライブ割り当てが必要となります。(仕様なのかどうなのかは不明)

PS C:\> $PSSession = New-PSSession TergetServer
PS C:\> Invoke-Command -Session $PSSession -ScriptBlock { net use x: \\FileServer\KB P@ssW0ord /user:HogeHoge }
コマンドは正常に終了しました。

PS C:\> $Terget = "C:\InstallKB"
PS C:\> Invoke-Command -Session $PSSession -ScriptBlock { if( -not ( Test-Path $args[0] )){ md $args[0] }} -ArgumentList $Terget


    ディレクトリ: C:\


Mode                LastWriteTime     Length Name                                  PSComputerName
----                -------------     ------ ----                                  --------------
d----        2015/04/19     16:37            InstallKB                             TergetServer


PS C:\> Invoke-Command -Session $PSSession -ScriptBlock { copy x:\Windows8.1-KB3042553-x64.msu $args[0] -Force } -ArgumentList $Terget
PS C:\> Invoke-Command -Session $PSSession -ScriptBlock { net use /delete x: /yes }
x: が削除されました。

PS C:\> Remove-PSSession $PSSession

 

Web Server から wget する

セキュリティ上の理由等でファイル共有(SMB)が使えない場合はどうするか。

そんな時は Web Server に対象ファイルを置いて、wegt で Pull する手があります。

wget は Linux でよく使われるコマンドで、http でファイルをダウンロードするコマンドです。

http は匿名アクセスが出来るので、wget では認証なしでファイルを pull する事が出来ます。

PoserShell 3.0 以降であれば Invoke-WebRequest が実装されており wget の Alias が割り当てられています。

注意点は、IIS では「MIMEの種類」で定義されていない拡張子を持つバイナリーファイルのダウンロードが出来ません。
拡張子を追加する場合は、MIMEの種類に「application/octet-stream」を指定して拡張子を登録します。

wget は以下の感じで使います

wget http://192.168.0.80/KB/Windows8.1-KB3042553-x64.msu -OutFile C:\InstallKB\Windows8.1-KB3042553-x64.msu

それでは、wget を使ってファイルを Pull させましょう。

PS C:\> $PSSession = New-PSSession TergetServer
PS C:\> $Terget = "C:\InstallKB"
PS C:\> Invoke-Command -Session $PSSession -ScriptBlock { if( -not ( Test-Path $args[0] )){ md $args[0] }} -ArgumentList $Terget


    ディレクトリ: C:\


Mode                LastWriteTime     Length Name                                  PSComputerName
----                -------------     ------ ----                                  --------------
d----        2015/04/19     17:00            InstallKB                             TergetServer


PS C:\> $SourceFile = "Windows8.1-KB3042553-x64.msu"
PS C:\> $URI = "http://192.168.0.80/KB/" + $SourceFile
PS C:\> $OutputFile = Join-Path $Terget $SourceFile
PS C:\> Invoke-Command -Session $PSSession -ScriptBlock { wget $args[0] -OutFile $args[1] } -ArgumentList $URI, $OutputFile
PS C:\> Remove-PSSession $PSSession

セキュリティを考えると、pull に使う Web Server は、外部からアクセスできないようしておくのが良いでしょう。

 

関連情報

Invoke-Command で KB をインストールする

リモート コンピューターのバッチ操作(Invoke-Command)

平文 ID Password から 資格情報を作成する

 

back.gif (1980 バイト)

home.gif (1907 バイト)

Copyright © MURA All rights reserved.