PowerShell 実践ガイドブック

という書籍がでました。

なおPowerShellから連想された表紙のイメージから貝殻本という俗称がついててTwitterのハッシュタグで正誤情報ほかいろいろ追えます。

続きを読む

Azure PowerShell の変更予定など

以下のようなアナウンスがされています。

もともとASM(Azure Service Management)とARM(Azure Resource Management)の2種類あってSwitch-AzureModeでモードをかえつつ使ってたのですが、2015年9月25日をターゲットに削除する予定のようです。

当初、Cmdletを同じにそろえようとしてたのですが議論の末、AzureRMという統一した名称になるようです。

[Verb]-Azure[Noun]なのが[Verb]-AzureRM[Noun]ですね。(Get-AzureRMVmのような感じで動詞と名詞(サービスやリソースなど)という感じです)
あとはモジュールの分割、PowerShell Gallery経由でのARMモジュールの配布、自動化されたドキュメントのMSDNへの追加などが予定されてるようです。

もともとARMへの移行が推奨されてた感じではありますが、今は過渡期ということでもろもろ変わることを前提にしておく必要があります。

なぜ変えるのか?というところですがまぁSwitch-AzureModeでModal/Statefulな挙動に不満が多かったんでしょうね。そもそも中途半端ですし。まぁそういうことで将来的な基盤を提供したいから破壊的変更させてくださいという感じです。

細かい理由やロードマップは最初に挙げたGitHubのページを参照ください。

まぁ個人的には早く全部ARMで管理できるようになることと、Azure Portalでフルコントロールできること、Azure PowerShellももっとシンプルになることを望みます。(ASMが無くなればもっとシンプルになるんだけど)

Get-AzureVMでout of range

なんかAzure PowerShellのGet-AzureVMとかGet-AzureDeploymentとかで得られる応答の一部要素(PersistentVMDowntimeのEndTime)でDateTime.MaxValueなISO8601形式の値(9999-12-31T23:59:59Z)が入ってるようで、こいつを日本みたいなUTCにプラスするタイムゾーン圏内でDateTime.Parseしようとして例外吐いてるみたいです。

> get-azurevm
get-azurevm : The DateTime represented by the string is out of range.
At line:1 char:1
+ get-azurevm
+ ~~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Get-AzureVM], FormatException
    + FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.ServiceManagement.IaaS.GetAzureVMCommand

仮想マシンをシャットダウンしたり再起動したりすると、EndTimeの値がまともな値になるのかちゃんと動作するようです。いやいや。。。

Management API側の挙動が変わったのかなー?(こんな値入ってたっけ?)という気がしますが、仮想マシンの再起動とかフザケンナという人はAzure PowerShellを実行するPCのタイムゾーンをUTCとかPSTにして凌ぎましょう。(なんとなくMSには報告済み)

DateTimeOffset使えば問題なさげだけど。

D:\> [System.DateTime]"9999-12-31T23:59:59Z"
Cannot convert value "9999-12-31T23:59:59Z" to type "System.DateTime". Error: "The DateTime repres ented by the string is out of range."
At line:1 char:1
+ [System.DateTime]"9999-12-31T23:59:59Z"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocationWithFormatProvider

D:\> [System.DateTimeOffset]"9999-12-31T23:59:59Z"


DateTime      : 9999/12/31 23:59:59
UtcDateTime   : 9999/12/31 23:59:59
LocalDateTime : 9999/12/31 23:59:59
Date          : 9999/12/31 0:00:00
Day           : 31
DayOfWeek     : Friday
DayOfYear     : 365
Hour          : 23
Millisecond   : 0
Minute        : 59
Month         : 12
Offset        : 00:00:00
Second        : 59
Ticks         : 3155378975990000000
UtcTicks      : 3155378975990000000
TimeOfDay     : 23:59:59
Year          : 9999

やれやれです。

2015.02.17 9:56 追記

Management REST API側で吐き出す値を修正したらしいです。とりあえず動作するようになりました。

Add-AzureAccountで組織アカウントが優先される問題 (解決)

以前、Add-AzureAccountで組織アカウントが優先されてしまう問題 という記事を書きましたが、今日リリースされたAzure PowerShell Cmdlets 0.8.8で修正されていました。

image

image

組織アカウントとMSアカウント両方もっていても正しく選択して認証することができます。

フィードバックした甲斐がありましたね。

というわけで困ってた人は0.8.8にアップデートしましょう。

Azure 仮想マシンとPowerShell DSCとか

DSC = Desired State Configuration の略ですが最近触ることになったので少しメモ。

DSCとは的な話は@IT/Build Insiderの記事とか、ぎたぱそ先生のBlog見てください。

あとAzure仮想マシンにDSC Extensionが追加されたのですがそちらの使い方などはムッシュ先生の記事を見るといいかと思います。

細かい話は上述の記事たちを見て頂くとわかるかと思います。

続きを読む

Azure PowerShell 0.8.6 で認証ダイアログが組織アカウント優先になってる

Azure PowerShell 0.8.6でMSアカウントと組織アカウントが同じメールアドレスの場合、Add-AzureAccountでMSアカウントのほうで認証しようとしても認証できないようです。

こまったちゃん。

0.8.5以前は以下のようにメアドいれると、それぞれ転送されててもしMSアカウントと組織アカウントがあるようだったら選択のダイアログが出ていました。

clip_image001[4]

clip_image001[6]

0.8.6だと組織アカウント優先のようで、

clip_image001[8]

選択の余地なし。もしCookieだか何だかよくわからないけど以前に管理ポータル等にサインインしたときの情報が残っていればキャンセルボタンからMSアカウントなりへの選択画面にうつれるのですが、、、

imageimage

先ほどの例みたいにキャンセルボタンもなければもうどうしようもなかったり。。。つらい。

一応、管理的にはAdd-AzureAccountを使わずにPublishSettingsファイルを使うとか(Import-AzurePublishSettingsFile)で管理はできそうですが。何のためのサインインダイアログなのだー

まぁ他にもCo-Adminするとかいろいろあるとは思いますが、なんだろう。パケットみるとちょっとだけOAuth2時のパラメータ違うのでその辺かなぁと思ってもどうしようもないですね。(AADのライブラリのバージョンによるのかな?謎)

とりあえずつたない英語でフィードバックだけはしておきました。

Azure PowerShell のあれこれ

Azure PowerShellも日進月歩な感じである意味時代の最先端(未発表機能が追加されてたり)をイッてるツールなわけですが今日はその小ネタを。

 

証明書が無いとかなんとかエラーがウザイ

%userprofile%\AppData\Roaming\Windows Azure Powershell フォルダにいろいろあるので、バッサリ消して初期化しちゃいましょう。うん。

 

Import-AzurePublishSettingsFile とか面倒くさいしウザイ

最近のバージョンでは Add-AzureAccount すればフェデレーション認証な感じでMSアカウントで認証して必要な権限をゲットできます。ほとんどのコマンドはこれだけで済むのでむっちゃ便利です。

Import-AzurePublishSettingsFile も便利なんですが、こいつに渡すファイルを Get-AzurePublishSettingsFile とかで取得するとその都度証明書作られたりウザイ。というわけでステステ。

※とはいえスクリプト内で実行する場合などは必要になるので、適宜ちゃんと作成・管理しましょう。

Import-AzurePublishSettingsFile 使わないと Add-AzureVhd でエラーになるんじゃ

clientCert cannot be null とか言うやつですね。わかります。なぜかAdd-AzureVhdだけ特殊な気が。。。

面倒くさいので New-AzureStorageContainerSASToken とかでSASを取得してアップロード先のURLにつけるといいですよ。

$sas = Get-AzureStorageContainer -Container vhds | New-AzureStorageContainerSASToken -Permission rwdl -ExpiryTime (Get-Date).AddDay(5)
$dest = "https://~~/vhds/test.vhd" + $sas

Add-AzureVhd -LocalFilePath $vhd -Destination $dest


こんな感じで。SAS便利だね☆

(5/9追記)SASの有効期間が短くてUpload中にエラーになったりするので、-ExpireTimeで長めの有効期限を渡しておきましょう。(例だと5日間)

はぁー、暇になりたい。

PSSnapInを自作する

メモ程度。

1. Visual Studio 2012でクラスライブラリを作る

2. System.Management.Automation と System.Configuration.Install の2つのアセンブリを追加する。(※System.Management.Automation は C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll にあるはず)

3. プロジェクトのプロパティで「ビルド後に実行するコマンドライン」でinstallutil.exeを使ってアセンブリをアンインストールする

c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil.exe $(TargetDir)$(TargetFileName)

※x64なアセンブリの場合はFramework64にしよう

image

※installutilを使ってインストールするので、Visual Studioは管理者権限で起動しておかないとうまくいかない(気がする)

4. デバッグ時に外部プログラムを開始するようにする

C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe

引数は以下のようにしてAdd-PSSnapInで読み込む

-noexit -command add-pssnapin buchizo.SnapinTest

image

5. SnapInクラスを継承したクラスを実装する

using System.ComponentModel;
using System.Management.Automation;

namespace buchizo.SnapInTest
{
	[RunInstaller(true)]
	public class buchizoSnapIn : PSSnapIn
    {
		public override string Description
		{
			get { return "test."; }
		}

		public override string Name
		{
			get { return "buchizo.SnapInTest"; }
		}

		public override string Vendor
		{
			get { return "buchizo"; }
		}
    }
}

 

RunInstaller(true)属性を忘れずに。

6. Cmdletクラスを継承してCmdletを実装する。

using System.Management.Automation;

namespace buchizo.SnapInTest
{
	[Cmdlet("Get", "Test")]
	public class GetTest : Cmdlet
	{
		protected override void ProcessRecord()
		{
			this.WriteObject("Test3");
		}
	}
}

 

細かいのはリファレンス参照で。

とりあえずこれで動く。デバッグ実行もOK

image

Azure Blob Storageのコンテナのパーミッションを変更する

小ネタです。Azure Storage Explorerだと出来なさそうだったのでPowerShellでサクッとAzure Blob Storageのコンテナのパーミッションを変更します。

  • Windows Azure PowerShell Cmdlets を利用するので、あらかじめインストールしておいてください。
  • 理屈的には大したことしてませんのでAzure SDKを使ったマネージコードでもできます。

Windows Azure PowerShell Cmdletsを起動して、Get-Containerコマンドでコンテナを取得します。

$container = Get-Container -StorageAccountName ***YourAzureStorageAccount*** -StorageAccountKey ***YourStorageKey***

 

取得できたらInstance(コンテナ)のGetPermission()メソッドを呼んで現在の権限を取得します。

$permission = $container[3].Instance.GetPermissions()

 

PublicAccessプロパティが現在の値です。(OffがPrivateコンテナ、ContanierがPublic Contanier、BlobがPublic Blobになります)

今現在はOffなのでPrivate(非公開)です。

image

image

このPublicAccessプロパティに”Container”等をセットし、Instanceプロパティ(コンテナ)のSetPermissions()メソッドを呼び出して設定を反映させます。

$permission.PublicAccess = "Container"
$container[3].Instance.SetPermissions($permission)

 

image

無事コンテナのアクセスレベルが変わりました。

image