Pythonの環境を他の人と共有したい
PythonUSBの環境を仮想ディスクで共有したいと思って、検討してみた。
diskpart でもある程度できるけど、batchから何度もpowershellを呼ぶと効率が良くないと思ってすべてpowershellで書き直してみた。
config
まずはコンフィグ。仮想ディスクのvolumeはディスクラベルで判別するので、ユニークな名前を。
GetFullPath を使っているのは、パスの正規化のため。
マウントは正規化されてなくてもOKなのに、アンマウントで見つからないと言われた。
なお、$C_VDISK_NAME
で、vhdx
にすると拡張子でファイルの種類変えるみたい。
# カレントパス
$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とかでいいと思います。
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"
にする必要あり。
これははじめ???となった。
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 {
}
仮想ディスクのアンマウント
マウント時の反対のことをしているので、特に特記事項はないけど、あえて言えば、
マウントされていないことをチェックするのにちょっと小細工。人によってはわかりにくいのかな・・・
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 {
}