2017/12/01

この記事はPowerShell Advent Calendar 2017の1日目です。

毎年恒例のPowerShell Advent Calendar、今年も始まりました。ここ数年は私がトップバッターを務めさせていただいて、1年間のPowerShell界隈の出来事をさくっとまとめてみています。→2016年2015年

昨年2016年はPowerShell 10周年の年であり、PowerShell 5.1、Windows Server 2016、Nano ServerとPowerShell Core Editionが各々正式版としてリリースされ、さらにはPowerShellがオープンソース化、マルチプラットフォーム展開を始めるという大きな変革があった年でした。

今年2017年は昨年ほど大きな変化はないとはいえ、昨年のOSS化からのマルチプラットフォーム展開を着実に進行させた年だと言えると思います。

以下、いくつかトピックを紹介します。

WMF 5.1インストーラーの登場

PowerShell 5.1を含むWMF (Windows Management Framework) 5.1は、Windows2016に同梱され、昨年8月にリリースされたWindows 10 Anniversary Updateにも同梱されました。今年1月に公開されたWMF5.1のインストーラーは、下位OS(Windows 7/8.1/Server 2008 R2/2012/2012 R2)のためのものです。

なお、Win10/2016に同梱のPester(テストフレームワーク)やPSReadline(コンソール入力支援)についてはWMF5.1には含まれていないので、別途PowerShellGetでインストールするのがお勧めです。

Azure Cloud ShellでのPowerShell サポート

Webブラウザ上で動作するAzureの管理用シェルである、Azure Cloud ShellではまずBashがサポートされていましたが、今年9月にPowerShellもサポート(まだプレビューですが)されました。

自動的に認証された状態で最新のAzure PowerShellのコマンドが使え、AzureのリソースにAzure:ドライブを介してアクセスすることが可能です。

注意点があって、このPowerShell版Azure Cloud Shell、どうも現バージョンでは(Nano Serverではなく)Windows Server Coreのコンテナ上で動作しているらしく、Bashに比べ起動が若干遅いのと、実体はPowerShell CoreではなくWindows PowerShell 5.1であることはちょっと念頭においておいたほうがいいかもしれません。

これ、PowerShell CoreではまだAzure PowerShellの全機能がサポートされてないからだと思うんですが、今後に期待ですね。

PowerShell for Visual Studio Code 正式版リリース

先だってオープンソース化された、マルチプラットフォーム対応のコードエディタであるVisual Studio CodeでPowerShellスクリプトの開発を行うためのExtension、PowerShell for Visual Studio Codeの正式版(1.0)が5月に公開されました。なお、現時点での最新バージョンは1.5.1となっています。

当初は、PowerShellに付属の標準スクリプト開発環境、PowerShell ISEの方が多機能だったようにも思いますが、今はもう完全にISEの機能を追い越したんじゃないかと思います。シンタックスハイライト、インテリセンス、デバッグ、コンソールといった基本機能はもちろん、Gitによるバージョン管理もVSCode自体でサポートされていることに加え、静的解析機能を提供するPowerShell Script Analyzer、テストフレームワークのPester、プロジェクト管理機能を提供するPlasterなどが統合されており、本格的な開発環境となっています。

また当然ではありますが、マルチプラットフォーム対応なので、WindowsではWindows PowerShell 、LinuxやMacではPowerShell Coreの開発が各々可能です。

公式ブログでのアナウンスによれば、今後ISEがなくなることはありませんが、ISEに新機能が追加されることはなくなり、PowerShell for VSCodeの開発に注力されることになります。ISEはとにかく標準添付である(GUI有効ならサーバーOSでも動く!)という強みがあり、シンプルなスクリプト記述であればそこそこ便利に使えるので、これからもシチュエーションに応じて使い分けて行けば良いのかなと思います。

PowerShell Core RCのリリース

昨年OSS化したPowerShell Core 6はα版として開発が続いていましたが、今年5月にはβ版となり、先月(11月)、ついにRC(Release Candidate)となりました。6.0.0のGAリリースは来年1月になるそうです。

OSS化直後からRCに至るまでの変更点は多岐に渡り、とても一言で説明できるものではないですが、ポイントとしては以下の3点に集約されるんじゃないかと思います。

  1. PowerShellが長年抱えていた問題点の洗い出しと修正

    PowerShellがOSS化した当初は、ほとんどがWindows PowerShell 5.1のコードそのままであったと言ってよいかと思います。10年以上増改築が繰り返されたコードが突如、全世界に公開されたわけです。コミュニティの力でバグや変な仕様といった問題点が洗い出され、どんどん修正されていきました。
    また、不足していると思われる機能はどんどん追加されました。既存コマンドレットのパラメータが増えるというパターンが多かったように思います。

    特筆すべきは、破壊的変更であっても妥当性があれば躊躇せずに取り入れていったことかと思います。これは英断ではありますが、一方でWindows PowerShell 5.1とPowerShell Coreでは細かいところで非互換性が色々出ていますので、移行の際には注意を要します。

  2. マルチプラットフォーム対応

    前述の通り、OSS化した当初のPowerShell 6.0は、ほぼWindows PowerShell 5.1なので、Windowsでしか動作しない部分が多々ありました。それをLinuxやMac環境でも動作するように多くの修正が加えられました。

    ところで、PowerShell 6.0は当初、条件付きコンパイルにより、Windows用に.NET Framework(Full CLR)をターゲットにして、Desktop Edition相当のPowerShellをビルドすることが可能でした。

    しかしβ版になったタイミングで、OSS版PowerShell 6.0は、「PowerShell Core 6.0」すなわち、「.NET Core上で動作するPowerShell Core」であることが明確にされました。よってFull CLRターゲットのビルドはできなくなり、β6ではついにFull CLR対応のコードはすべて削除され、Core CLR対応のコードのみとなりました。

  3. Windows PowerShell用コマンドレットの呼び出し

    PowerShell Core 6.0にはいくつかのコマンドレットが同梱されていますが、Windows PowerShell 5.1に含まれているすべてのコマンドレットを網羅しているわけではありません。また、WindowsやWindows Serverの管理のために提供されている、OS付属のモジュール群もCore 6.0には含まれておらず、α版の段階では実行も不可能(だったはず)でした。

    β1からターゲットが.NET Core 2.0に移行したことにより、.NET Standard 2.0がサポートされました。このことによって、Windowsに付属の数千ものコマンドレットを初めとするWindows PowerShell用コマンドレット(要はFull CLRをターゲットとしてビルドされたもの)のうち、.NET Standard 2.0に含まれるAPIしか使われていないものであれば、原理的にはPowerShell Coreでも実行可能になりました。

Windows PowerShellの今後

さて、PowerShell Core 6.0がまもなく正式版リリースということですが、では従来のWindows PowerShellはどうなるのか、という話について。

公式ブログのアナウンスによれば、Windows 10やWindows Server 2016に付属のWindows PowerShell 5.1については、今後もサポートライフサイクルに則り、重大なバグフィックスやセキュリティパッチ提供等のサポートは継続されます。もちろん下位バージョンのOS/Windows PowerShellも同様です。

しかしながら、Windows PowerShellに新機能が追加されることは今後はなく、開発のメインはPowerShell Coreへと移行します。つまりは、PowerShell Coreの開発の中で追加された新機能、変更点、バグフィックスについては、基本的にはWindows PowerShellとは無関係ということです。

また、現状ではPowerShell CoreはWindows PowerShell環境に追加インストールし、サイドバイサイド実行が可能となっていますが、将来的にPowerShell CoreがWindowsに同梱されるかどうかについては言及されておらず、今のところは不明です。

以下は私見になります。

このような状況で、Windows PowerShellユーザー、とりわけWindows Serverの管理はするが、Linuxとかは特に…というユーザーはこれからどうすべきか?という点は割と悩ましいところだと思います。個人的には、WindowsやWindows Serverを管理するスクリプトが現時点であるなら、それを無理に今すぐCore対応にする必要はないと思います。現時点で今すぐCoreに移行すべき理由というのはとくに無いと感じます。Coreで追加、改善された機能はあるものの、Coreには無い機能もたくさんあるからです。
また新規にスクリプトを作る場合でも、対象がWindowsに限定されるのであれば、Windows PowerShell用に作れば良いのではないかと。OS付属のコマンドレットの動作は確実に保証されているわけですから。

ただし、ご存じの通りWindows10とServer 2016は半期に一度の大型アップデートで新機能が次々追加されていきます。その過程でPowerShell Coreが含まれるようになったり、Coreのみ対応のコマンドレットが追加される可能性は無きにしもあらずなのではないかとも思います。なので、Coreの状況をチラ見しつつ、未来に備えておく必要はあると思います。Windows10/Server2016の「次」も見据えて。

それとPowerShellでWindowsもLinuxも面倒みていきたい、という野心がある方は、Coreを採用していくのがいいのではないかと思います。ただし、現状しばらくは茨の道ではあるとは思います。

あとはスクリプトやモジュールを作成し公開する方は、より多くの環境で使われるように、可能であればCore対応を進めるのは悪くないんじゃないかと思います。

おわりに

他にもWin10/Server2016におけるPowerShell 2.0の非推奨化の話とか、DSC Core構想とか、なにげに結構いろいろ話題はありました。

さて、Windows PowerShellとしては一端落ち着いた感もある界隈ですが、PowerShell Coreとしてはこれからも活発に動いていくものと思います。注目していきたいですね。

そんな2017年の締めくくり、今年はどんな記事が集まるでしょうか。PowerShell Advent Calendar 2017の参加、お待ちしております。

2016/04/23

Japan PowerShell User Group (JPPOSH) 主催の第 6 回 PowerShell 勉強会(4/9)には多数の方にお越しいただき、ありがとうございました。

PowerShell勉強会は今後も年2回くらいのペースで続けて行きたいと思っていますので、どうぞよろしくお願い致します。

さて、私のセッション「PowerShell 5.0 新機能と関連OSSのご紹介」のスライドを公開します。前半は以前のものとだいたい同じですが、正式版対応版にアップデートしています。

今回は去年から今年にかけて、PowerShell関連ソフトウェアとしてOSS化したものを、まとめて紹介しました。以下は今回紹介したもののリストです。

またデモで用いたサンプルファイルも公開します。

このzipにも同梱してますが、PSScriptAnalyzerのカスタムルールはこんな感じで作ります。作り方は、ASTを受け取って、中身をチェックして、ルールに該当するならDiagnosticRecordを返すというのが基本になります。

using namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
using namespace System.Management.Automation.Language

Import-Module PSScriptAnalyzer

function Test-UsingVarsWithNonAsciiCharacter
{
    # 変数に半角英数字以外の文字種が含まれていると警告するカスタムルール。
    [CmdletBinding()]
    [OutputType([DiagnosticRecord[]])]
    Param
    (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [ScriptBlockAst]
        $ScriptBlockAst
    )

    Process
    {
        [Ast[]]$variableAsts = $ScriptBlockAst.FindAll({
            param([Ast]$ast)
            $ast -is [VariableExpressionAst]
        }, $true)

        $variableAsts | 
        where {
            $_.VariablePath.UserPath -notmatch '^[a-zA-z0-9_]+$'
        }|
        foreach {
            $result = [DiagnosticRecord[]]@{
                "Message"  = "変数 `$$($_.VariablePath.UserPath) に半角英数字以外の文字種が使われています。"
                "Extent"   = $_.Extent
                "RuleName" = "AvoidUsingVarsWithNonAsciiCharacter"
                "Severity" = "Warning"
            }
            $result
        }
    }
}
Export-ModuleMember Test-UsingVarsWithNonAsciiCharacter

ついでにPesterのサンプルコードも。2つのパラメータを足し算する関数、Invoke-Additionに対するテストコードの例となります。

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

Describe "Invoke-Addition" {   # テストの定義
    Context "足し算の実行" {   # テストのグループ化
        It "整数値を2個指定すると、足し算された結果が返る" {  # テストケース
            Invoke-Addition 3 5 | Should Be 8 # アサーション
        }

        It "小数値を2個指定すると、足し算された結果が返る" {
            Invoke-Addition 3.4 5.8 | Should Be 9.2
        }
    }

    Context "エラーの発生" {
        It "足し算できないものを指定するとエラー" {
            {Invoke-Addition 10 "x"} | Should Throw 
        }
    }
}

2015/12/01

この記事はPowerShell Advent Calendar 2015の1日目です。

アドベントカレンダーは今年で5回目ですが、例年よりだいぶ参加者が少ないので、敢えて完走を目指さずまったりいきましょう。

とはいえ今年から来年にかけては、PowerShellの変革の年といっても過言ではないかと思います。

今年7月にはWindows 10のリリースとともに、WMF (Windows Management Framework) 5.0 / PowerShell 5.0 (2012R2/8.1向けにはProduction Preview)が登場しました。(私の書いたPS5.0新機能のセッション資料はこちら。)

PowerShell 5.0では特に、"Infrastructure as Code"、すなわちインフラの構成をコードで記述可能にし自動化するための機能である、PowerShell DSC周りが格段にパワーアップしています。DSCの機能増強により、Microsoft Azure等のクラウド、オンプレミスのサーバーはともに大きな恩恵を受けることが期待されます。Azure DSC Extensionも追従する形で凄まじい勢いでバージョンアップしてますね。

PowerShell 5.0の登場に合わせて、各種のPowerShell関係のモジュールやアプリケーションが新登場していますが、これらはいずれもOSS(オープンソースソフトウェア)となりました。

一例を挙げると、DSCで用いるロジック本体となる「DSCリソース」を作製する際に有用なDSCリソースキット、対応リポジトリをプロバイダという形で拡張可能であるパッケージ管理システムPackageManagement、PowerShellモジュールを専用リポジトリであるPowerShell Galleryからコマンド1発で取得可能となるPowerShellGet、PowerShellスクリプトの静的解析を行うスクリプトアナライザー、Windowsのみならず他プラットフォームの一括管理を目指すDSC for Linux等々です。

先日OSS化したばかりの、マルチプラットフォーム対応のコードエディタであるVisual Studio Codeと、PowerShellスクリプトが記述可能となるPowerShell Extensionあたりもトピックとして熱いですね。

Visual Studio 2015には、VSでPowerShellスクリプト開発を行うためのOSSなプラグインであるPowerShell Tools for Visual Studioが標準搭載されたことも記憶に新しいですね。(12/1追記)

逆に、PowerShellのテストスクリプトを記述するためのフレームワーク(DSL)であるPesterや、コンソールの入出力をパワーアップさせるPSReadlineといった、OSSで開発されている既存のPowerShellモジュールが、Windows 10に標準機能として取り込まれるなど、OSSとの関係性については大きく変化したと言えるでしょう。

そして次期Windows Serverである、Windows Server 2016の足音も聞こえてきました。現在はTP4が公開されており、試すことができます。Windows Server 2016の目玉は何といっても、Windows ContainersNano Serverでしょう。

アプリケーションをコンテナという単位で配置し、自由なすげ替え、あるいは使い捨てが可能な環境を構築するツールであるDockerというOSSに対し、インターフェースの互換性を持たせたWindows版コンテナがWindows Containersです。

そして、コンテナ機能を最大限に活用するためにフットプリントの最小化を目指し、GUIどころかコンソールすら廃した新しいWindows Serverの形態が、Nano Serverです。

Windows ContainersとNano Serverの管理は当然、PowerShellがメインとなります。また、ようやくWindowsにやってくる、SSHクライアントとサーバーはPowerShell上で動くようです。

PowerShellは5.0に進化することで、足回りを強化しました。そして各種OSSと連携して、クラウドとオンプレミスのサーバー群の基礎を支える存在として、ますます重要性を帯びていくことでしょう。

昨今のPowerShellを取り巻く状況は、私の理解ではざっとこんな感じです。この中に興味を持たれたテーマはありませんか? もちろん、新機能以外にも、まだまだ知られていない機能や利用法も埋もれていると思います。

もしそんなテーマがあったら、PowerShell Advent Calendar 2015で共有していただければ嬉しいなあと思います。

というわけで、例年にない感じの初日記事を書いてみました。今回のアドベントカレンダーもどうぞよろしくおねがいします。

2014/09/09

8/23わんくま横浜勉強会で、PowerShellコマンドの書き方というセッションをしたのですが、その際、株式会社Codeerさんが公開されているFriendlyというライブラリを使ったコマンドレットを動作させるデモを行いました。

準備の時間がなくて、突貫工事で作ったサンプルで恐縮ですが、公開することにします。(一応動かしてみたら動いた、レベルのものなのであしからず…)

コード
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using Codeer.Friendly.Windows;
using Codeer.Friendly.Dynamic;
using System.Windows.Forms;

namespace Winscript
{
    [Cmdlet(VerbsCommon.Get, "FormControlText")]
    public class GetFormControlTextCommand : Cmdlet
    {
        [Parameter(Mandatory = false, ValueFromPipeline = false, Position = 1)]
        public string[] ControlName { get; set; }

        [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0)]
        public Process Process { get; set; }

        protected override void ProcessRecord()
        {
            var _app = new WindowsAppFriend(this.Process);
            dynamic form = _app.Type<Control>().FromHandle(this.Process.MainWindowHandle);
            foreach (var c in form.Controls)
            {
                if (ControlName == null || ControlName.Contains((string)c.Name))
                {
                    WriteObject((string)c.Text);
                }
            }
        }
    }

    [Cmdlet(VerbsCommon.Set, "FormControlText")]
    public class SetFormControlTextCommand : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = false, Position = 1)]
        public string ControlName { get; set; }

        [Parameter(Mandatory = true, ValueFromPipeline = false, Position = 2)]
        public string Text { get; set; }

        [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0)]
        public Process Process { get; set; }

        protected override void ProcessRecord()
        {
            var _app = new WindowsAppFriend(this.Process);
            dynamic form = _app.Type<Control>().FromHandle(this.Process.MainWindowHandle);
            foreach (var c in form.Controls)
            {
                if (ControlName == (string)c.Name)
                {
                    c.Text = Text;
                }
            }
        }
    }
}
ビルド方法
  1. Windows 8.1 SDK をインストールする。
  2. Visual Studio 2010以降でC#のクラスライブラリを新規作成する。
  3. C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0 にある.dllを参照設定する。
  4. 対象フレームワークを.NET 4.5、対象プラットフォームをx64にする。
  5. 上記のコードを貼り付ける。
  6. NuGetでFriendlyおよびFriendly.Windowsを追加する。
  7. ビルドする。
使用方法

上記をビルドして生成したDLLにはGet-FormControlTextと、Set-FormControlTextの2つのコマンドレットが含まれます。

# コマンドレットのインポート
Import-Module "dllのフルパス"

# 操作対象のプロセスオブジェクト取得
$p = Get-Process WindowsFormsApplication1 

# プロセスを指定して、すべてのコントロールのテキストを取得
Get-FormControlText -Process $p

# プロセスとコントロール名を指定して、テキストを取得
Get-FormControlText -Process $p -ControlName textBox1

# 位置パラメータなので以下のようにも書ける
Get-FormControlText $p textBox1

# パイプラインからプロセスオブジェクトを入力することもできる
$p | Get-FormControlText -ControlName textBox1 

# プロセスとコントロール名を指定して、テキストを変更する
Set-FormControlText -Process $p -ControlName textBox1 -Text Wankuma
Set-FormControlText $p textBox1 Yokohama
$p | Set-FormControlText -ControlName textBox1 -Text 6
制限事項

フォーム直下に配置されたコントロールしか取得できない(と思います)。

Windows Formアプリケーションにしか対応していない(と思います)。

x64アプリしか操作できない(と思います。x86用はアセンブリを分ける必要がある??)。(←9/9追記)

コントロール名指定はCase sensitiveでワイルドカード不可です。(この辺ただの手抜きですが)

今後の方針?

上のコードをみてもらえればわかると思いますが、ちょっと触ってみたら一応動くものができるくらい、Friendlyは分かりやすいです。皆さんもぜひ使ってみてください。

本来は、テキストじゃなくてコントロールそのものをGetしたりSetしたりInvoke(クリックとか)したりできるようにしたかったんですが、Controlはシリアル化できないオブジェクトなので、Friendlyで実物を持ってきてコマンドレットに出力する、というのは無理でした。何らかのプロキシオブジェクトみたいなのでラップしたりすれば良いかと思います。

それにしてもPowerShellとFriendlyの組み合わせはものすごい可能性を秘めている予感がします。

システム管理方面では…

セッションでもやりましたが、PowerShellコマンドレットベースのアプリケーションを作ると、GUIとCUIのいいところどりが出来る、とはいうものの、コマンドインターフェースがなくGUIオンリーのアプリケーションはまだまだたくさんあるのが現実かと思います。そういうアプリケーションも、PowerShellデフォルトの機能のみではつらいですが、上記のようにFriendlyを併用すれば、GUI操作の自動化が容易になると思います。

開発方面では…

C#でFriendlyを使ったGUIのテストコードを書く以外に、上記のようなFriendlyの機能をラップしたコマンドレットを用意することで、PowerShellスクリプトでもテストコードを書くことができるようになると思います。その際、Pester等のPowerShell用テストフレームワークを併用すると、より一貫したテストコードが記述できるようになるんじゃないかと思います。

いずれは(いつ?)、Friendlyの機能をラップしたコマンドレット群をきちんと設計、実装して、モジュールとして公開したいですね!



Copyright © 2005-2018 Daisuke Mutaguchi All rights reserved
mailto: mutaguchi at roy.hi-ho.ne.jp
プライバシーポリシー

Books

Twitter