先週ちょっと東京へ行く用事があり、それに合わせてAzureもくもく会@新宿に参加した際に調べた内容をまとめたエントリです。
AzurePSDriveとは
AzurePSDriveはAzure CloudShell(PowerShell)を起動した際のカレントロケーションがPS Azure:\>となるアレを提供する仕組みです。

PowerShellのドライブはファイルシステム以外にも階層構造をもつデータであれば拡張して扱うことが可能であり、AzurePSDriveではAzureのサブスクリプションとそれに紐づく各リソースをドライブとして扱うことができる様になります。
類似のものとしてはIISの設定を行うWebAdminstrationモジュールのIISドライブや、SqlServerモジュールのSQL Serverドライブなどがあり、こちらの方がイメージがつかみやすいかもしれません。
ソースコード
AzurePSDriveはGitHubでそのソースが公開されています。
英語ですが基本的な概念や使い方もこちらに記載されています。
AzurePSDriveの実装について
ここから本題に入ります。
Azure Cloud Shellの環境で実際にAzurePSDriveを使いながらその実装を追っていきます。
Simple Hierarchy in PowerShell(SHiPS)
AzurePSDriveでは独自のドライブを実装するのにSimple Hierarchy in PowerShell(SHiPS)と呼ばれるPowerShellモジュールを利用しています。
このモジュールは従来独自の実装が必要であったPSドライブを簡易に作成するためのモジュールであり、SHiPSDirectoryやSHiPSLeafといったクラスを継承したクラスを作ることで簡単に階層構造を表現することができる様になります。
詳しい話と実装例がぎたぱそ先生の本(4.9.14 SHiPSとクラスを使ったPSドライブの自作)に書いてますので気になる人はぜひご覧ください。(宣伝)
- 作者: 吉崎生
- 出版社/メーカー: マイナビ出版
- 発売日: 2018/05/30
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
以下同書のサンプルコードを例として紹介します。
# SHiPSの実装例 # https://github.com/guitarrapc/Book-PowerShell-Samples/blob/master/Book-PowerShell-Samples/Chapter4/4.9_Class/PSDrive/SolarSystem.psm1 より抜粋 using namespace Microsoft.PowerShell.SHiPS # SHiPSDirectory を継承したクラスでコンテナとなる要素を定義 class SolarSystem : SHiPSDirectory { # ・・・中略・・・ } # SHiPSLeaf を継承したクラスで枝要素を定義 class Moon : SHiPSLeaf { # ・・・中略・・・ }
Azure PowerShellモジュールと独自の型定義
AzurePSDriveは内部でAzureのリソースにアクセスする際にAzure PowerShell moduleの機能を利用しています。
Windows PowerShell、PowerShell Core両方に対応しており、現時点のバージョン(Ver.0.8.7)では、
- AzureRM.Profile (AzureRM.Profile.NetCore)
- AzureRM.Resources (AzureRM.Resources.NetCore)
- AzureRM.Compute (AzureRM.Compute.NetCore)
- AzureRM.Websites (AzureRM.Websites.NetCore)
- Azure.Storage (Azure.Storage.NetCore)
が依存モジュールとなっています。
また、内部的にはAzure PowerShell moduleのオブジェクトをそのまま使っている部分があるのですが、一部オブジェクトについてはドライブ独自の型に差し替えられています。
例として、改めて後述しますが、AllResources要素ではGet-AzureRmResourceの結果である Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResource型のオブジェクトをそのまま使っているのですが、この型がAzurePSDriveではAzurePSDriveResourceTypeになります。
細かい説明は省きますが、実装としては以下の様にして取得したオブジェクトの型を差し替えています。
# AzurePSDriveResource.psm1 より一部抜粋 & "$script:AzureRM_Resources\Get-AzureRmResource" | %{ $_.psobject.typenames.Insert(0, "AzurePSDriveResourceType"); $_ }
CloudShellログイン時点
ここからはAzure Cloud Shell(PowerShell)の実際の画面を基に各階層の内容について説明していきます。
最初にAzure Cloud Shellにログインした時点では最上位の階層であるAzureドライブがカレントロケーションとなります。

Get-PSDriveを使うとこのAzureドライブの情報を見ることができます。
PS Azure:\> Get-PSDrive | Format-Table -AutoSize Name Used (GB) Free (GB) Provider Root CurrentLocation ---- --------- --------- -------- ---- --------------- / 15.01 33.40 FileSystem / home/stknohg Alias Alias Azure SHiPS AzurePSDrive#Azure Env Environment Function Function Variable Variable
ファイルシステムなどのドライブの中にAzureドライブが存在し、SHiPSプロバイダーとして定義されていることが分かります。
第1階層 : サブスクリプション
AzureドライブでGet-ChildItem(dir)を実行すると子要素を一覧することができ、たとえば私のアカウントだと以下の様に表示されます。
PS Azure:\> dir
Directory: Azure:
Mode SubscriptionName SubscriptionId TenantId State
---- ---------------- -------------- -------- -----
+ stknohg ********-****-****-****-************ ********-****-****-****-************ Enabled
最初の階層はログインしたアカウントに紐づくサブスクリプションが列挙されます。
各サブスクリプションはSubscription型として定義されており、内部的にはACC_TID環境変数が定義されていればそのテナントID、ACC_TID環境変数が定義されていない場合は(Get-AzureRmTenant)[0].IdとなるテナントIDに紐づくサブスクリプションをGet-AzureRmSubscriptionで取得しています。
ちなみに現在Azure Cloud Shellは全てLinux(Ubuntu)のコンテナになってしまったため、lsコマンドは/bin/lsなのでAzureドライブの子要素を取得するのには使えませんので注意してください。
第2階層 : リソース分類
つづけてSet-Location(cd)でサブスクリプション(ここではstknohg)に移動し、子要素を一覧すると以下の様になります。
PS Azure:\> cd ./stknohg/
PS Azure:\> dir
Directory: Azure:/stknohg
Mode Name
---- ----
+ AllResources
+ ResourceGroups
+ StorageAccounts
+ VirtualMachines
+ WebApps
SubScriptionの子要素は以下で固定されています。
- AllResources
- ResourceGroups
- StorageAccounts
- VirtualMachines
- WebApps
それぞれ名前から予測はつくと思いますが詳細は後述します。
第3階層(AllResouces)
ここからはSubScriptionの各子要素について説明します。
最初にAllResources要素についてです。
この要素はAllResources型で表現され、内容としては単純にGet-AzureRmResourceの結果を返しているだけになります。
さらなる子要素はありません。
通常Get-AzureRmResourceの結果は Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.PSResource型ですが、表向きの型をAzurePSDriveResourceTypeに更新しており、Get-Memberで取得できる型名は後者となっています。
第3階層(ResourceGroups)
ResourceGroups要素がおそらくAzurePSDriveで扱うメインの要素になるかと思います。
この要素はResourceGroups型で表現され、子要素にResourceGroup型のオブジェクトを持ちます。
実装としては、Get-AzureRmResourceGroupとGet-AzureRmResourceを内部で使い、各リソースを呼出してリソースの階層構造を表現しています。
ここから第4階層(ResourceProvider)、第5階層(ResourceType)と続くのですが説明が冗長になる*1ので本エントリではこのくらいにしておきます。
第3階層(StorageAccounts)
ここからのStorageAccounts、VirtualMachines、WebAppsについてはリソースの中でもよく使うであろうものを特別視したものと思われます。
(もしかしたら子要素の表現が難しいものを特別視している可能性もありますが、ちょっと断言できません...)
この要素はStorageAccounts型で表現され、Get-AzureRmStorageAccountの結果を子要素にStorageAccount型として持ちます。
StorageAccountの子要素として各ストレージの種類に応じた、
- Blobs
- Files
- Tables
- Queues
がありそれぞれの情報にアクセスすることができます。
内部的にはAzure.Storage (Azure.Storage.NetCore)モジュールの各コマンドレットが使われ、その結果を利用しています。
第3階層(VirtualMachines)
この要素はVirtualMachines型で表現され、 Get-AzureRmVMの結果をAzurePSDriveVM型として子要素に持ちます。
これ以上の階層は無く、単純にVMの一覧が取得できて終わりの様です。
第3階層(WebApps)
この要素はWebApps型として表現され、Get-AzureRmWebAppの結果をAzurePSDriveWebApp型として子要素に持ちます。
この要素もこれ以上の階層は無く、単純にWebAppの一覧が取得できて終わりです。
最後に
とりあえずこんな感じです。
私自身Azureをさほど使いこなしていないため、ソースを読み間違えている部分があるかもしれません。
もし本エントリの内容におかしな点がありましたらフィードバックしていただけると嬉しいです。
*1:調べきれなかったとも言います...