適材適所

WindowsやPowerShellやネットワーク、IBMなどのシステム系の話など気になったことも載せているブログです。

PowerShellでシステムパス(Desktop)などの場所を知りたいときに見る記事

デスクトップやマイドキュメントのパス

PowerShellでスクリプトを書いていると、環境に左右されないパスを使いたいことがよくあります。

ユーザーフレンドリーを目指して、マイドキュメントやデスクトップにファイルを吐き出したいときなど。

そんなときに役立つ、PowerShellでデスクトップやマイドキュメントを取得する方法を紹介したいと思います。

環境

$PSVersionTable
NameValue
---------
PSVersion5.1.18362.752
PSEditionDesktop
PSCompatibleVersions{1.0, 2.0, 3.0, 4.0...}
BuildVersion10.0.18362.752
CLRVersion4.0.30319.42000
WSManStackVersion3.0
PSRemotingProtocolVersion2.3
SerializationVersion1.1.0.1

主な方法は2つ

デスクトップのような特殊なパス(システムパス)の場所を知るための方法はPowerShellでは主に2つあります。

1つ目は、.NETのSystem.Enviroment::GetFolderPathを使う方法。

2つ目は、WSHのSpecialFoldersを使う方法。

どちらも同じようなパスを取得することができますが、1つ目の方が多くのパスを取得することができます。

基本的には1つ目の方法を取るのがベストプラクティスかと思います。

では、2つの方法で、どんなパスが取得できるのか見ていくことにしましょう。

[System.Enviroment]::GetFolderPath

.NETのEnviromentクラスを使うことでシステムパスを取得することができます。

取得できるフォルダの一覧

 
[System.Enum]::GetValues([System.Environment+SpecialFolder])
Desktop
Programs
MyDocuments
MyDocuments
Favorites
Startup
Recent
SendTo
StartMenu
MyMusic
MyVideos
DesktopDirectory
MyComputer
NetworkShortcuts
Fonts
Templates
CommonStartMenu
CommonPrograms
CommonStartup
CommonDesktopDirectory
ApplicationData
PrinterShortcuts
LocalApplicationData
InternetCache
Cookies
History
CommonApplicationData
Windows
System
ProgramFiles
MyPictures
UserProfile
SystemX86
ProgramFilesX86
CommonProgramFiles
CommonProgramFilesX86
CommonTemplates
CommonDocuments
CommonAdminTools
AdminTools
CommonMusic
CommonPictures
CommonVideos
Resources
LocalizedResources
CommonOemLinks
CDBurning

たくさんのシステムパスを取得できることがわかりました。

各パスの詳細については公式ドキュメントに記載がありますので、そちらをご参照ください。

Desktopのパスを取得する場合

では、Enviromentクラスを使ってDesktopのパスを取得してみましょう。

具体的にはEnviromentクラスのGetFolderPathメソッドに取得したいパスの名前を指定します。

 
[System.Environment]::GetFolderPath("Desktop")
C:\Users\User\Desktop

値とフォルダの一覧を作成

GetFolderPathで得られる戻り値が実際にどのフォルダを指すかは、下記のコマンドで確認することができます。

 
$ary=@();[System.Enum]::GetValues([System.Environment+SpecialFolder])|%{$ary+=(New-Object psobject -Property @{value=$_; path=([System.Environment]::GetFolderPath($_))})};$ary|format-list
value : Desktop
path: C:\Users\USER\Desktop

value : Programs
path: C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs

value : MyDocuments
path: C:\Users\USER\Documents

以下省略

WSHのSpecialFolders

WSHのSpecialFoldersプロパティを使ってもシステムパスを取得することができます。

WSHのSpecialFoldersについては、こちら↓が参考になります。

第6回 WshShellオブジェクトの詳細(2):Windows管理者のためのWindows Script Host入門(1/3 ページ) - @IT

下準備

PowerShellでWSHを使うためには下準備が必要です。

 
$shell=New-Object -ComObject Wscript.shell

取得できるフォルダの一覧

下準備ができたら、SpecialFoldersプロパティを呼びだすことで取得できるシステムパスの一覧を確認することができます。

 
$shell=New-Object -ComObject Wscript.shell
$shell.SpecialFolders
C:\Users\Public\Desktop
C:\ProgramData\Microsoft\Windows\Start Menu
C:\ProgramData\Microsoft\Windows\Start Menu\Programs
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
C:\Users\USER\Desktop
C:\Users\USER\AppData\Roaming
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Printer Shortcuts
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Templates
C:\Windows\Fonts
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Network Shortcuts
C:\Users\USER\Desktop
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu
C:\Users\USER\AppData\Roaming\Microsoft\Windows\SendTo
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Recent
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
C:\Users\USER\Favorites
C:\Users\USER\Documents
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs

WSHでDesktopのパスを取得する場合

WSHのSpecialFoldersでDesktopのパスを取得するには次のようにします。

 
$shell.SpecialFolders("Desktop")
C:\Users\USER\Desktop

こちらもわかりやすいですね。

GetFolderPathとSpecialFoldersの違い

両者とも手軽に使えますが、実は取得できるパスが微妙に違っています。

取得したいパスによっては、両者を使い分ける必要があります。

取得できるシステムパスの違いを比較してみる

Compare-Objectを使って、

両者の違いを確認してみましょう。

 
$environment=([System.Enum]::GetValues([System.Environment+SpecialFolder])|%{[System.Environment]::GetFolderPath($_)})
$shell=New-Object -ComObject Wscript.shell
$wscript= $shell.SpecialFolders
Compare-Object -ReferenceObject $environment -DifferenceObject $wscript
InputObject: C:\Program Files
SideIndicator : <=

以下省略

私の環境だとSideIndicatorが<=しかありませんでした。

つまり、.NETのGetFolderPathの方が取得できるパスが多いことを示しています。

というわけで結論としては、「GetFolderPathを使った方が無難」というところに落ち着きそうです。

終わりに

PowerShellでシステムパス(Desktop)などの特殊なパスを取得する方法を紹介しました。

これらをうまく使えば、環境に左右されないスクリプトを作ることができます。

ユーザーフレンドリーなスクリプトを作る際には重宝すること請け合いです。

ここまでお読みいただき、ありがとうございました。