参考
- Windows PowerShell ドライブの管理
- PowerShell で 共有ドライブ(マップドライブ)を作成する
やりたいこと
- バッチ処理の中で、他のWindowsサーバにネットワークドライブ接続したい
- ネットワークドライブ接続した後に、メインの処理(copyなど)をして、終わった時に切断したい
- 使っていいドライブ文字列(G〜Pまでの間)から、空いているドライブ文字列を使いたい
コード
# ネットワークドライブ接続
# 1. 使用済みドライブ文字を配列格納
[array]$usinglist = get-psdrive |%{$_.name}
# 2. 使用しても良い全てのドライブ文字を配列格納
[array]$alldrivelist = @("G","H","I","J","K","L","M","N","O","P")
# 3. 2.と1.を比較し、現在利用可能なドライブ文字を格納
[array]$availablelist = Compare-Object $alldrivelist $usinglist |?{$_.SideIndicator -match "<="}|%{$_.InputObject}
# 4. 3.で作った配列のうち、最初の1文字を選択し、使用するドライブ文字とする
$drivelettertoconnect = $availablelist[0]
# 5. 4.で作った、使用するドライブ文字にマウントするパスを変数格納
$SharePath = "\\localhost\c$"
# 6. ネットワークドライブ接続(このPowershellセッションのみで使用可能)
New-PSDrive -Name $drivelettertoconnect -PSProvider FileSystem -Root $SharePath
# 7. やりたい処理(copyなど)
# 8. exitする。(ネットワークドライブも自動で削除される)
exit $exitcode
解説
1.使用済みドライブ文字を配列格納
2.使用しても良い全てのドライブ文字を配列格納
3. 2.($alldrivelist)と1.($usinglist)を比較し、現在利用可能なドライブ文字を格納
-
まず、Compare-Objectで2つの配列にある要素を比較できる。SideIndicatorが「<=」となっているものが、2. (alldrivelist)にあって、1. (usinglist)にない要素。つまり、使用済みでないドライブ文字列。
4. 3.で作った配列(availablelist)のうち、最初の1文字を選択し、使用するドライブ文字とする
5. 4.で作った、使用するドライブ文字(drivelettertoconnect)にマウントするパス(CIFS)を変数格納
ネットワークドライブ接続
- New-PSDrive コマンドレットを用いて、ネットワークドライブを作成
- New-PSDrive -Name (使用するドライブ文字) -PSProvider FileSystem -Root (マウントするパス)
補足
-
作成したドライブは、ドライブを作成したPowershellセッションのみで使用可能です。
-
-Credential オプションを用いて、資格情報も埋め込み可能です。
- インターネットにいい記事がたくさんあるので割愛
-
エラー処理、例外については別途実装する必要があります。
-
Powershellの基本的な書き方について、slideshareに資料をupしています。
追記(2017/10/09)
検証したサンプルコード載せときますね。scope指定も使いました(作成したネットワークドライブをスクリプト内、関数外で有効にするために)。
# 引数受け取り
Param(
[string]$userid, # ユーザ名
[string]$SharePath, # マウント先
[string]$logfile # 出力ログ
)
# 資格情報取得
$passwdfile = "C:\pass.txt"
function Make-PSCredential($ID){
try {
$exitcode = 0
$PlainPassword = import-csv $passwdfile |?{$_.user -like $ID} |%{$_.Password}
$SecurePassword = ConvertTo-SecureString -String $PlainPassword -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($ID, $SecurePassword)
} catch [Exception] {
$exitcode = 1
$error |out-file -Append $logfile
exit $exitcode
} finally {
"資格情報取得処理 $exitcode で終了します。0=正常、1=異常。" |out-file -Append $logfile
}
Return $Credential
}
$credential = Make-PSCredential -ID $userid
# ネットワークドライブ接続(exitで切断)
function net-use ($cifspath,$cred) {
try {
$exitcode = 0
# 1. 使用済みドライブ文字を格納
[array]$usinglist = get-psdrive |%{$_.name}
# 2. 使用しても良い全てのドライブ文字を格納
[array]$alldrivelist = @("G","H","I","J","K","L","M","N","O","P")
# 3. 2.から1.を引いて、現在利用可能なドライブ文字を格納
[array]$availablelist = Compare-Object $alldrivelist $usinglist |?{$_.SideIndicator -match "<="}|%{$_.InputObject}
# 4. 3.で作った配列のうち、最初の1文字を選択し、使用するドライブ文字とする
$drivelettertoconnect = $availablelist[0]
# 5. ネットワークドライブ接続
New-PSDrive -Name $drivelettertoconnect -PSProvider FileSystem -Root $cifspath -credential $cred -Scope script -ErrorAction Stop >null 2>&1
return "${drivelettertoconnect}:"
} catch [Exception] {
$exitcode = 2
$error |out-file -Append $logfile
exit $exitcode
} finally {
"ネットワークドライブ接続処理 $exitcode で終了します。0=正常、1=異常。" |out-file -Append $logfile
}
}
$connecteddrive = net-use $SharePath $credential
# 6. メイン処理(copy)
try {
$exitcode = 0
copy "${connecteddrive}\pass.txt" "C:\PerfLogs\" -ErrorAction stop >null 2>&1
} catch [Exception] {
$exitcode = 3
$error |out-file -Append $logfile
exit $exitcode
} finally {
"コピー処理 $exitcode で終了します。0=正常、1=異常。" |out-file -Append $logfile
}
# 7. 終了
exit 0
以上