PowerShellでネットワークドライブ(NAS等)を接続・切断
本記事は、TechCommit AdventCalendar 2024 の16日目の記事です。
はじめに
自宅PCのWindowsでNASとして運用しているサーバのWindows上のPowerShellから接続したり取り外したりということを時々やります。と言うのも、常時接続してなかったりするストレージを右クリックしてウィザード起動したりなんだりが面倒なのでターミナルでやっちゃいたい為。
その時に私が個人用で使ってるスクリプトの事例を小ネタとして紹介します。
記載する事例は完全に私の自宅環境での運用事例なのですが、ご自宅などの小規模なネットワークの作業などの参考にしてみてください。
要約すると
「ネットワークの場所の追加ウィザード」等と同じような操作をPowerShellでやる方法を私の自宅流で解説しています。
ローカルネットワークにあるデバイスIPを取得
Get-NetNeighbor
を使うとローカルネットワークのデバイスのIPを取れます。
これでよく家のNASのアドレスなどをチェックしたりしています。例えば192.168.0.3
みたいなヤツです。
Get-NetNeighbor -InterfaceIndex 4 -AddressFamily IPv4 -State Stale, Reachable
ドライブのリスト
Get-PSDrive
で見れます。Linuxなどでのdf
みたいなものです。
Get-PSDrive -PSProvider FileSystem
ドライブの接続
New-PSDrive
を使うと(今回の文脈ではネットワーク)ドライブの接続を行います。
ポイントとしては-Persist -Scope Global
を指定する所で、ドライブを強制的に無期限に保持することを有効化します。これを使うことで「エクスプローラ」などでドライブの接続が永続化されます。
私の家でのNASではユーザ名とパスワードを必要とする一般的なタイプですが、これはSystem.Management.Automation.PSCredential
を使ってクレデンシャルのオプションとして与えます。
以下ではローカルNASのアドレス・ユーザ・パスワードを入力させ、
D..Z
の適当なドライブ名を割り当てて接続を確立させる例を示します。
$addr = (Read-Host "Enter the IP address of the server").Trim()
$user = (Read-Host "Enter username").Trim()
$password = Read-Host "Enter password" -AsSecureString
$credential = New-Object System.Management.Automation.PSCredential($user, $password)
if ($addr.Length -eq 0 -or $user.Length -eq 0 -or $password.Length -eq 0) {
Write-Error "Please enter all the required fields."
exit 1
}
# Normalize the address
if (!$addr.StartsWith("\\")) {
$addr = "\\" + $addr
}
$addr = $addr.Replace("/", "\")
$used_drive_names = Get-PSDrive -PSProvider FileSystem | Select-Object -ExpandProperty Name
$available_drive = "D" .. "Z" | Where-Object { $_ -notin $used_drive_names } | Select-Object -First 1
if ($available_drive) {
try {
New-PSDrive -Name $available_drive -PSProvider FileSystem -Root $addr -Credential $credential -Persist -Scope Global -ErrorAction Stop
}
catch {
Write-Error "$_"
}
}
上手くいくと以下のようにエクスプローラで表示されます。
ドライブの取り外し
Remove-PSDrive
というコマンドレットがあるのですが、困ったことにこのコマンドレットはポンコツで、ネットワークドライブを外すのに私の環境だと動作しないので、ここはnetコマンドで切ってます。
以下ではドライブ名を入力するプロンプトを表示・入力させ、「G」ドライブなどのネットワークドライブを接続していた場合(DisplayRoot
で判定)、指定したドライブをnet /delete
によって切断する例を示します。
$drive_name = Read-Host "Enter the drive name to remove"
if ($drive_name.EndsWith(":")) {
$drive_name = $drive_name.Substring(0, $drive_name.Length - 1)
}
if ($drive_name.Length -eq 0) {
Write-Error "Please provide the drive name to remove."
exit 1
}
$drive = Get-PSDrive -Name $drive_name -PSProvider FileSystem
if ($drive -and $drive.DisplayRoot.StartsWith("\\")) {
try {
$_drive = $drive.Name + ":"
net use $_drive /delete
}
catch {
Write-Error "$_"
}
}
Discussion