LoginSignup
1
3

More than 1 year has passed since last update.

PowerShellで仮想ディスクを構築/マウント/アンマウントする方法

Posted at

Pythonの環境を他の人と共有したい

PythonUSBの環境を仮想ディスクで共有したいと思って、検討してみた。

diskpart でもある程度できるけど、batchから何度もpowershellを呼ぶと効率が良くないと思ってすべてpowershellで書き直してみた。

config

まずはコンフィグ。仮想ディスクのvolumeはディスクラベルで判別するので、ユニークな名前を。
GetFullPath を使っているのは、パスの正規化のため。
マウントは正規化されてなくてもOKなのに、アンマウントで見つからないと言われた。
なお、$C_VDISK_NAMEで、vhdxにすると拡張子でファイルの種類変えるみたい。

00_config.ps1
# カレントパス
$C_CUR_PATH = Split-Path $MyInvocation.MyCommand.Path

# 仮想ディスクのラベル
$C_VDISK_LABEL = "Python"

# 仮想ディスクのファイル名
$C_VDISK_NAME = "Python.vhd"
$C_VDISK_FILE = [IO.Path]::GetFullPath( (Join-Path $C_CUR_PATH $C_VDISK_NAME) )

# 仮想ディスクのマウント先
$C_MOUNT_NAME = "..\Python"
$C_MOUNT_PATH = [IO.Path]::GetFullPath( (Join-Path $C_CUR_PATH $C_MOUNT_NAME) )

仮想ディスクの構築

管理者権限に移行時、パスが変わるので、スクリプトのパスに初めに戻るようにしている。
仮想ディスクを作って、フォーマットまでします。

なお、このスクリプトでは、bitlockerの暗号化回避できないかと思って、FAT32使ってるけど、意味はなかった。普通にvhdxにしてexFatとかでいいと思います。

01_CreateDisk.ps1

Set-Location -LiteralPath $PSScriptRoot

. .\00_config.ps1

if ( Test-Path $C_VDISK_FILE ) {
  echo "既にファイルが存在します"
  exit
}

if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) {
  Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs -Wait
  exit
}

New-VHD -Path $C_VDISK_FILE -SizeBytes 32GB | Mount-VHD -Passthru | Initialize-Disk -Passthru | New-Partition -UseMaximumSize | Format-Volume -NewFileSystemLabel $C_VDISK_LABEL -FileSystem FAT32 -Confirm:$false -Force

Dismount-VHD $C_VDISK_FILE

仮想ディスクのマウント

既にマウント済みか、ディスクラベルでチェックし、なければ管理者に移行してマウント。
管理者権限移行時、ウィンドウがじゃなであれば、 -WindowStyle Hiddenを付ければいいけど、
エラーがわからなくなるので戻しました。
エラーメッセージも消したい場合は、$ErrorActionPreference = "Stop"にする必要あり。
これははじめ???となった。

02_MountDisk.ps1
Set-Location -LiteralPath $PSScriptRoot

. .\00_config.ps1

if ( !(Test-Path $C_VDISK_FILE) ) {
  echo "ファイルが存在しません. " + $C_VDISK_FILE
  exit
}

foreach ( $e in Get-Volume ) {
  if( $e.FileSystemLabel -eq $C_VDISK_LABEL) {
    echo "マウント済みです"
    exit
  }
}


if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) {
  # Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs -Wait -WindowStyle Hidden
  Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs -Wait
  exit
}

$ErrorActionPreference = "Continue"
try {
  Mount-VHD $C_VDISK_FILE
} catch {

}

try {
  Get-Volume -FileSystemLabel $C_VDISK_LABEL | Get-Partition | Add-PartitionAccessPath -AccessPath $C_MOUNT_PATH
} catch {

}

仮想ディスクのアンマウント

マウント時の反対のことをしているので、特に特記事項はないけど、あえて言えば、
マウントされていないことをチェックするのにちょっと小細工。人によってはわかりにくいのかな・・・

03_UnmountDisk.ps1
Set-Location -LiteralPath $PSScriptRoot

. .\00_config.ps1

if ( !(Test-Path $C_VDISK_FILE) ) {
  echo "ファイルが存在しません. " + $C_VDISK_FILE
  exit
}

:MOUNTED do {
  foreach ( $e in Get-Volume ) {
    if( $e.FileSystemLabel -eq $C_VDISK_LABEL) {
      break MOUNTED
    }
  }
  echo "マウントされてません"
  exit
} while( $false )


if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) {
  # Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs -Wait -WindowStyle Hidden
  Start-Process powershell.exe "-File `"$PSCommandPath`"" -Verb RunAs -Wait
  exit
}

$ErrorActionPreference = "Continue"
try {
  Get-Volume -FileSystemLabel $C_VDISK_LABEL | Get-Partition | Remove-PartitionAccessPath -AccessPath $C_MOUNT_PATH
} catch {

}

try {
  Dismount-VHD $C_VDISK_FILE
} catch {

}
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3