しばたテックブログ

気分で書いている技術ブログです。

PowerShellコンソールの表示色についてのちょっとした話

ちょっと面白いIssueを見つけたので。

github.com

このIssue自体は以下の様に前景色にDarkYellowを指定した場合に表示される色がおかしいというものです。

Write-Host '████████' -ForegroundColor DarkYellow

確かにWindowsで試すと下図の様に黄色ではなく灰色が表示されます。

f:id:stknohg:20160914231324p:plain

PowerShellにおけるコンソールの表示色について

Issue内でも回答されていますが、これはバグではなく仕様です。
PowerShellに限らずコンソールプログラム全般の仕様でもあります。

先ほどの例の様にWrite-Host-ForegroundColor-BackgroundColorで指定できる色はSystem.ConsoleColor型で

メンバー名
0 Black
1 DarkBlue
2 DarkGreen
3 DarkCyan
4 DarkRed
5 DarkMagenta
6 DarkYellow
7 Gray
8 DarkGray
9 Blue
10 Green
11 Cyan
12 Red
13 Magenta
14 Yellow
15 White

の16色あります。

これらの色はPowerShellのプロパティ"画面の色"タブにあるカラーパレットに対応しており、カラーパレットの色を変えるとコンソールの表示色も変わります。

f:id:stknohg:20160914232915p:plain:w480

以下のコードを実行してConsoleColorの各色を表示させてみると、

[System.Enum]::GetValues([System.ConsoleColor]) | % { Write-Host "■" -ForegroundColor $_ -NoNewline }

下図の様になりカラーパレットの色と一致します。

f:id:stknohg:20160914233956p:plain

問題となったDarkYellowは左から7番目のボックスとなり灰色(238,237,240)が設定されてるため名前と実際の色が一致しない事になっています。

ちなみにコマンドプロンプトの場合は黄色(128,128,0)が割り当てられておりPowerShellで(238,237,240)に変更されています。
このほかに6番目のボックスもマゼンタ(128,0,128)から(1,36,86)と変更されています。
どうやら使用頻度の低い色をPowerShell用にカスタマイズしている様です。

PowerShell on Linux(Mac)のコンソール表示色について

とりあえず仕様であることはわかりましたが、これだけではつまらないのでPowerShell on Linux(Mac)についても調べてみます。

例としてUbuntu上のPowerShellで最初のコードを実行すると、以下の図の様になり良い感じの黄色が表示されます。

f:id:stknohg:20160914235506p:plain

当然ですがLinuxやMacには先ほどのカラーパレットはありません。

[System.ConsoleColor]の各色は.NET Coreによって対応するANSIエスケープシーケンスに置き換えられてコンソールに表示されます。

変換テーブルがConsolePal.Unix.cs_consoleColorToAnsiCodeに以下の様に定義されています。

// ConsolePal.Unix.cs より

/// <summary>
/// The values of the ConsoleColor enums unfortunately don't map to the 
/// corresponding ANSI values.  We need to do the mapping manually.
/// See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
/// </summary>
private static readonly int[] _consoleColorToAnsiCode = new int[]
{
    // Dark/Normal colors
    0, // Black,
    4, // DarkBlue,
    2, // DarkGreen,
    6, // DarkCyan,
    1, // DarkRed,
    5, // DarkMagenta,
    3, // DarkYellow,
    7, // Gray,

    // Bright colors
    8,  // DarkGray,
    12, // Blue,
    10, // Green,
    14, // Cyan,
    9,  // Red,
    13, // Magenta,
    11, // Yellow,
    15  // White
};

DarkYellow3なので最初の例だと

# あくまで変換イメージです
echo -e "\033[33m■■■\033[m"

と変換されるイメージです。

PowerShell ISEのコンソール表示色について

最後にPowerShell ISEについて調べてみます。
PowerShell ISEで最初のコードを試した結果は以下の様になり、こちらも良い感じの黄色が表示されます。

f:id:stknohg:20160915001935p:plain

PowerShell ISEでは[System.ConsoleColor]の各色を独自の変換テーブルで[System.Windows.Media.Color]に変換します。
変換テーブルはMicrosoft.PowerShell.GPowerShell.dllMicrosoft.Windows.PowerShell.Gui.Internal.GPSHostRawUserInterfaceクラスに定義されており、残念ながらこのクラスはオープンソース化していないためILSpy等で中身を見てみると以下の様になっていることがわかります。

// Microsoft.Windows.PowerShell.Gui.Internal.GPSHostRawUserInterface より

internal static readonly Color[] ConsoleColors = new Color[]
{
    Colors.Black,
    Colors.DarkBlue,
    Colors.DarkGreen,
    Colors.DarkCyan,
    Colors.DarkRed,
    Colors.DarkMagenta,
    Color.FromRgb(170, 170, 0),
    Colors.DarkGray,
    Colors.Gray,
    Colors.Blue,
    Colors.Lime,
    Colors.Cyan,
    Colors.Red,
    Colors.Magenta,
    Colors.Yellow,
    Colors.White
};

ここからDarkYellowは(170,170,0)に変換されることがわかります。
他の色は定義済みの色なのでそのままですね。

PowerShell on Linuxに普通にPSRemotingしてみる

ある意味前回の続き的な。

注意事項

一応PSRemotingできるのは確認しましたが、まだアルファ版なので動作が超不安定です。
実際に使える様になるのはまだまだ先になりそうな感じです。

OMI ServerとPowerShell on Linux OMI Provider

WindowsのPSRemotingではWinRMサービスがエンドポイントとなりリモートからの接続を受け付けています。
当然ですがLinuxにはWinRMサービスはないため代替になる機能が必要です。

それが、OMI ServerPowerShell on Linux OMI Providerになります。

OMI Server

私自身まだ勉強中なため簡単な説明で済ませます。
間違いがあればご指摘ください。

まず、Open Management Infrastructure (OMI)は、超簡単に言うと、オープンソースのUNIX/Linux向けのWBEM実装になります。
雑なイメージですがUNIX/Linux向けのWMIと考えれば話は早いかと思います。

公式な情報はThe Open Groupにありソースもここで公開されていたのですが、先日GitHubでもソースが公開されニュースになりました。

OMIの概要についてはWindows Server Blogの以下の記事が詳しいので参考にしてください。

blogs.technet.microsoft.com

この記事にある様にOMIはいくつかのコンポーネントから成るのですが、今回インストールするのはその中のomiserverと呼ばれるコア機能になります。

PowerShell on Linux OMI Provider

OMI Serverはコア機能でそれだけあっても正直使いものになりません。
利用したい機能に応じてProviderと呼ばれるコンポーネントを追加してやる必要があります。

WMIの場合はOSに組み込み済みなためあまり意識しませんが、ココにある様に数多くのProviderが存在しています。

PowerShell on Linux向けのOMI ProviderがGitHubで公開されていますので、これを追加してやることでPowerShell Remoting Protocol(PSRP)によるリモート接続ができる様になります。

余談ですが、その他の機能を利用する場合は個別にOMI Providerをインストール、または自作する必要があります。
例えばPowerShell DSCをLinuxで利用する場合、ココにあるDSC Packagesをインストールする必要があり、ソースをよく見るとDSC ResourceごとにOMI Provdierの定義があることがわかります。

動作環境

PowerShell on Linux OMI ProviderのGitHubに以下のIssueが上がっており、現時点ではUbuntu 14.04でのみ動作可能な様です。

github.com

私も最初CentOS 7.2で試してみましたが同じエラーが出て駄目でした。
また、理由は不明ですがUbuntu 14.04でもDocker上では駄目な様です。
これも最初に試して失敗しました。

これをふまえて今回はWindows 10 RS1(1607)の物理マシンからHyper-V上に構築したUbuntu Server 14.04.5の仮想マシンに接続して検証しました。
UbuntuはISOからインストールしてSSHだけ初期インストールした状態です。

PowerShell on LinuxにPSRemotingしてみる

最初にDocker環境で試した都合*1、以降の手順は全てrootで行っています。

1. PowerShellのインストール

最初にPowerShellをインストールします。

https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md#ubuntu-1404github.com

こちらは特に言うことはありません。
GitHubからPowerShellのdebファイルをダウンロードしてdpkgでインストールします。

# apt-get update and install PowerShell
apt-get update && apt-get install -y curl libunwind8 libicu52 libcurl3
curl -LO https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell_6.0.0-alpha.9-1ubuntu1.14.04.1_amd64.deb
dpkg -i powershell_6.0.0-alpha.9-1ubuntu1.14.04.1_amd64.deb

2. OMI Serverのインストール

次にOMI Serverをインストールします。
手順はGitHubに載っています。

github.com

といってもOSに応じたdebファイルをインストールするだけなので楽です。
一応ソースからビルドする手順も載っていますが面倒なのでしません(

# Install OMI
curl -LO https://github.com/Microsoft/omi/releases/download/v1.1.0-0/omi-1.1.0.ssl_100.x64.deb
dpkg -i omi-1.1.0.ssl_100.x64.deb

3. PowerShell on Linux OMI Providerのインストール

最後にOMI Providerをインストールします。
こちらも手順はGitHubに載っています。

github.com

必要なパッケージ(libpam0g-devlibssl-dev)とdebファイルをインストールするだけです。

# Install Powershell OMI Provider
apt-get install -y libpam0g-dev libssl-dev
curl -LO https://github.com/PowerShell/psl-omi-provider/releases/download/v.1.0/psrp-1.0.0-0.universal.x64.deb
dpkg -i psrp-1.0.0-0.universal.x64.deb

インストール後はserviceコマンドでOMI Server(omid)の状態を確認してください。
通常であればrunningになっているはずで、これで準備完了です。

root@ubuntu:/# service omid status
Checking for service Microsoft OMI Server  *  is running

もしomidが起動していない場合は起動しておいてください。

# omidが起動していない場合は以下のコマンドで起動します
service omid start

ちなみにデフォルトではTCP 5986(HTTPS)で待ち受けをします。

oot@ubuntu:/# netstat -lp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 *:5986                  *:*                     LISTEN      2138/omiserver

・・・ (後略) ・・・

なお、今回はやりませんでしたが、Firewallが有効な場合はTCPの5985,5986番ポートをあけておいてください。

4. PSRemotingしてみる

OMI Providerのインストール手順に記載されている手順で接続します。

OMI Serverインストール時に生成される証明書が自己証明書であることや、接続先の指定にIPアドレスを使っているといった都合、以下の様にNew-PSSessionOptionを使って幾つかのチェックをスキップするオプションを指定してやる必要があります。

# PowerShell 5.1 / Windows 10
# Ubuntuサーバーが 192.168.0.200 の場合
$o = New-PSSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck
Enter-PSSession -ComputerName 192.168.0.200 -Credential root -Authentication basic -UseSSL -SessionOption $o

また、接続ユーザーは必ずrootにしてください。
現状root以外のユーザーで接続するとエラーになってしまいます。

接続できると下図の様になり、普通にPSRemotingできます。

f:id:stknohg:20160909181047p:plain

これで今回の目的は果たせましたが、せっかくなのでCIMセッションを張ってOMIの情報も取得してみます。
(といっても現状Providerが全然無いので大した情報は取れませんが...)

New-CimSessionOptionNew-CimSessionを使ってUbuntuに対してCIMセッションを張ります。
指定するオプションはPSセッションの場合とだいたい同じです。

# PowerShell 5.1 / Windows 10
# Ubuntuサーバーが 192.168.0.200 の場合
$o = New-CimSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck -UseSsl
$s = New-CimSession -ComputerName 192.168.0.200 -Credential root -Authentication Basic -SessionOption $o

セッションを張った後は、Get-CimInstanceを使うとCIMインスタンスの情報を取れます。
(現在取れるのはOMI Server自身のクラスであるOMI_Identifyの情報しかありませんが。)

Get-CimInstance -CimSession $s -Namespace root/omi -ClassName OMI_Identify

実行すると下図の様になりOMI Serverの情報が取れました。

f:id:stknohg:20160909181814p:plain

続けてGet-CimClassを使ってCIMクラスの情報を取得してみます。
Windowsであれば以下の様にすれば利用可能なクラスの一覧が取得できるのですが、Ubuntuで試すと内部エラーになってしまいました。
そういう仕様なのかバグなのかはよくわかりません。

Get-CimClass -CimSession $s

仕方ないので以下の様にクラス名まで指定してやる必要があります。

Get-CimClass -CimSession $s -Namespace root/omi -ClassName OMI_Identify

結果は下図の様になり、クラスのプロパティなどの情報を取得できます。

f:id:stknohg:20160909182137p:plain

現時点ではOMIのクラスが全然ないため何の役にも立ちませんが、いずれ*2クラスが増えることがあればWindowsでWMIを使ったサーバー管理をしてきたのと同じ様にLinux(ひいてはMac)の管理ができる様になるはずです。

期待して待つか気合を入れて自作しましょう(

エラーが出た場合

最初に述べた様にこのOMI ServerとOMI Providerは超不安定です。
何らかのエラーが出てomidが落ちると、以降何をやっても接続不可になるケースが頻発します。

もしそうなった場合はOMI Providerを再インストールすると直ります。

# omid 停止
service omid stop
# アンインストール
dpkg -r omi-psrp-server
# 再セットアップ
dpkg -i psrp-1.0.0-0.universal.x64.deb

これでもダメな場合は気合でなんとかするか、諦めてゼロから再セットアップするしかないと思います。

追記

PowerShell on Linux OMI Providerをソースからビルドする手順について書きました。

stknohg.hatenablog.jp

*1:Dockerfileの内容を単純にコピペしたかったので...

*2:いつになることやら...

PowerShell Remoting over SSHを試す

PowerShell Core 6.0の正式リリースに伴い、本エントリの内容を新しいバージョンでやり直しました。
こちらのエントリを参照してください。

blog.shibata.tech


PowerShell on Linux(Mac)が公開された際の新機能の一つにSSHによるPSRemoting(PowerShell Remoting over SSH)があります。

本エントリではこの機能を試してみます。

PowerShell Remoting over SSHとは

ドキュメントでの表記がPowerShell Remoting over SSHPowerShell Remoting Protocol(PSRP) over SSHPSRP over OpenSSH等と若干揺れているのですが本エントリではPowerShell Remoting over SSHで統一しておきます。

従来のPowerShell Remoting Protocol(PSRP)では通信の下回りにHTTP/HTTPSを使いますが、PowerShell Remoting over SSHでは名前の通りSSHを使った通信を行います。

基本的な仕組みとしては、

  1. クライアント側はpowershell(.exe)がリモートセッション生成時にssh(.exe)を呼び出し、powershell(.exe)→ssh(.exe)のプロセス間通信を経由してサーバーへの通信を行う。
  2. サーバー側はSSHdのサブシステムにPowerShellを登録。
    クライアントからの接続があった場合はsshd(.exe)→powershell(.exe)とリモートシェルが実行される。

となっています。

仕様が公開されれいないため、ソースを読んだ限りでですが、PowerShell Remoting over SSHの仕組みはJobやPowerShell Directと同類でPSRPは(たぶん)使用しておらずWinRMにも依存していません。
このため、あくまでも私見ですが、PSRP over SSHという表記は正確でないと思われます。

このあたりはもう少し時間が経てば公式な情報も増えてくるかと思います。

PowerShell Remoting over SSHを試す

手順はGitHubDocsで公開されているのでこの手順をベースに行います。

https://github.com/PowerShell/PowerShell/tree/master/demos/SSHRemoting

試験環境

試験環境はVirtualBox上でWindows Server 2012 R2とCentOS 7.2.1511を使い双方向で通信させてみます。
これらのOSにした理由は単純に私が使い慣れているだけです。

他のOSでも細かい部分に違いはあるでしょうが基本的には同じ流れになると思います。

その他細かい条件は以下。

項目 Windows Server 2012 R2 CentOS 7.2.1511
基本設定 インストール直後の状態+最新のWindows Updateを実施 bento/centos7.2のBoxにyum updateを実施
IP 192.168.33.210 192.168.33.209
ユーザー vagrant, administrator vagrant, root

Windows → CentOSへの通信(パスワード認証)

最初にWindowsをクライアント、CentOSをサーバーにした場合の接続を試します。

CentOSにPowerShellをインストールします。  

# CentOS bash
# PowerShellのインストール
sudo yum install https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell-6.0.0_alpha.91.el7.centos.x86_64.rpm -y

SSHdの設定変更を行います。
/etc/ssh/sshd_configに次の設定を追加します。

Subsystem powershell powershell -sshs -NoLogo -NoProfile

追加例)

# /etc/ssh/sshd_config

# override default of no subsystems
Subsystem       sftp    /usr/libexec/openssh/sftp-server
Subsystem powershell powershell -sshs -NoLogo -NoProfile

また、必要に応じてパスワード認証、鍵認証の可否を設定します。
今回は試験環境のデフォルト設定のままとしました。

# Boxのデフォルト設定
PasswordAuthentication yes

#RSAAuthentication yes
#PubkeyAuthentication yes

設定変更後はSSHdを再起動します。

# CentOS bash
sudo systemctl restart sshd.service

これでCentOS側の設定は完了です。

次にWindows側の設定をします。
標準でインストールされているPowerShell 4.0ではPowerShell Remoting over SSHできませんので、こちらにもPowerShell Coreをインストールします。

# Windows PowerShell 4.0
# PowerShell Coreのインストール
Invoke-WebRequest -Uri "https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/PowerShell_6.0.0.9-alpha.9-win81-x64.msi" -OutFile "PowerShell_6.0.0.9-alpha.9-win81-x64.msi"
Start-Process -FilePath msiexec.exe -ArgumentList @("/i", "$($pwd.Path)\PowerShell_6.0.0.9-alpha.9-win81-x64.msi", "/passive") -Wait -PassThru

次にSSHをインストールします。
Zipの解凍をしたいので先ほどインストールたPowerShell Coreから以下の手順でインストールします。

# Windows PowerShell Core
# ssh.exeのインストール 
Invoke-WebRequest -Uri "https://github.com/PowerShell/Win32-OpenSSH/releases/download/5_30_2016/OpenSSH-Win64.zip" -OutFile "OpenSSH-Win64.zip"
Expand-Archive -Path ".\OpenSSH-Win64.zip" -DestinationPath "C:\"
[Environment]::SetEnvironmentVariable('PATH', [Environment]::GetEnvironmentVariable('PATH') + ';C:\OpenSSH-Win64')

インストール先はC:\OpenSSH-Win64としましたが、こちらについては必要に応じて変更しても構いません。
また、PowerShell Remoting over SSHではssh.exeに対してPATHが通っていること(正確にはssh.exeだけでコマンド呼び出しができること)が必須であるためPATHは必ず通す様にしてください。

これで準備が整いましたので実際に試してみます。

まずはNew-PSSessionでPSセッションを作成します。
-HostName(-ComputerNameではない)、-UserNameパラメーターを指定するとPowerShell Remoting over SSHで通信することになります。

# Windows PowerShell Core
$Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant

実行すると以下の様にssh.exeを使ってサーバーに接続する際のあれやこれやを聞かれるので適切な情報を入力していきます。

# Windows PowerShell Core
PS C:\Users\Administrator> $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant
The authenticity of host '192.168.33.209 (192.168.33.209)' can't be established.

ECDSA key fingerprint is SHA256:*******************************************.
Are you sure you want to continue connecting (yes/no)?
Please type 'yes' or 'no':
vagrant@192.168.33.209's password:

入力後、エラーが出なければ成功です。
$Sessionの中身を確認すると以下の様になり、名前がSSHになっていることがわかります。
このセッションがssh.exeと紐づいています。

# Windows PowerShell Core
PS C:\Users\Administrator> $Session

 Id Name            ComputerName    ComputerType    State         Configuration
                                                                  Name
 -- ----            ------------    ------------    -----         -------------
  1 SSH1            192.168.33.209  RemoteMachine   Opened        DefaultShell

この$sessionを使いEnter-PSSessionしてリモート接続します。

# Windows PowerShell Core
Enter-PSSession -Session $Session

実行結果は以下の様になり、CentOSにリモート接続できました。

# Windows PowerShell Core → CentOS PowerShell
PS C:\Users\Administrator> Enter-PSSession -Session $Session
[192.168.33.209]: PS /home/vagrant> cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[192.168.33.209]: PS /home/vagrant>

ちなみに既知の不具合としてリモートだとClear-Hostが使えません。
これはそのうち直ると思います。

# Windows PowerShell Core → CentOS PowerShell
# Clear-Hostはエラーになる
[192.168.33.209]: PS /home/vagrant> Clear-Host
TERM environment variable not set.

とりあえずエラーメッセージの通りに

$env:TERM="vt100"

等とTERM環境変数を適当に設定しておけば対処は可能です。

最後にRemove-PSSessionしてセッション情報を削除すると紐づいていたssh.exeも終了します。

# Windows PowerShell Core
Remove-PSSession -Session $Session
  
# 個別に消すのが面倒なら以下で一気に消しても良い
Get-PSSession | Remove-PSSession

Windows → CentOSへの通信(鍵認証)

鍵認証で通信する場合、基本的にSSHの鍵認証の方法と同一です。

先ずはWindows側でssh-keygen.exeで鍵を作ります。
鍵の種類やパスフレーズの有無は適当にしてください。

以下の実行例ではRSA2 4096Byte、パスフレーズ有りにしています。

# Windows PowerShell 4.0 (Coreでもたぶん良い)
PS C:\> cd C:\OpenSSH-Win64\
# ssh-keygen
PS C:\OpenSSH-Win64> .\ssh-keygen.exe -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\Administrator/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): ********
Enter same passphrase again: ********
Your identification has been saved in C:\Users\Administrator/.ssh/id_rsa.
Your public key has been saved in C:\Users\Administrator/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:******************************************* Administrator@WIN-7JINTK1PS1K

The key's randomart image is:
+---[RSA 4096]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+----[SHA256]-----+

あとは作った公開鍵(id_rsa.pub)をCentOS側に転送し~/.ssh/authorized_keysに追加するだけです。
以下の例では/vagrant/id_rsa.pubに鍵を転送しています。

# CentOS bash
# ユーザーはvagrantユーザー
cat /vagrant/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

これで鍵認証の準備は完了です。
鍵認証で接続する場合はNew-PSSession-KeyPathパラメーターを使用します。

実行例は以下

# Windows PowerShell Core
# エラーが出なければ成功
PS C:\> $Session = New-PSSession -HostName 192.168.33.209 -UserName vagrant -KeyPath ~\.ssh\id_rsa
Enter passphrase for key 'C:\Users\Administrator\.ssh/id_rsa': ********

# セッション情報を確認
PS C:\> $Session

 Id Name            ComputerName    ComputerType    State         Configuration
                                                                  Name
 -- ----            ------------    ------------    -----         -------------
  1 SSH1            192.168.33.209  RemoteMachine   Opened        DefaultShell

セッションが生成された後はパスワード認証の場合と同様です。

CentOS → Windowsへの通信(パスワード認証)

最後に、あまり需要があるとは思いませんが、CentOSをクライアント、Windowsをサーバーにした場合の接続を試します。
面倒なのでパスワード認証のみとします。

まずはWindows上でSSHdを動作させます。
基本的にはGitHub上のインストール手順に従うだけなので問題ないかと思います。

# Windows PowerShell 4.0
cd C:\OpenSSH-Win64\

# SSHdのインストール
.\install-sshd.ps1

# ホストキーの作成
.\ssh-keygen.exe -A

# Firewall設定
New-NetFirewallRule -Protocol TCP -LocalPort 22 -Direction Inbound -Action Allow -DisplayName SSH

# 鍵認証周りの設定+再起動
.\install-sshlsa.ps1
Restart-Computer

sshd_configの設定はCentOSの場合と同様でサブシステムにPowerShell(Coreの方)を登録します。

Subsystem powershell C:/Program Files/PowerShell/6.0.0.9/powershell.exe -sshs -NoLogo -NoProfile

追加例)

# C:\OpenSSH-Win64\sshd_config

# override default of no subsystems
Subsystem   sftp    C:/Program Files/OpenSSH/sftp-server.exe
Subsystem powershell C:/Program Files/PowerShell/6.0.0.9/powershell.exe -sshs -NoLogo -NoProfile

設定後はサービスを再起動します。

# Windows PowerShell 4.0(Coreでもよい)
Restart-Service sshd

これで準備は完了です。

CentOS側からWindowsへ接続してみます。

# CentOS PowerShell
PS /home/vagrant> $Session = New-PSSession -HostName 192.168.33.210 -UserName administrator
The authenticity of host '192.168.33.210 (192.168.33.210)' can't be established.
ECDSA key fingerprint is ***********************************************.
Are you sure you want to continue connecting (yes/no)? yes
administrator@192.168.33.210's password: ********

セッション情報はこんな感じです。

# CentOS PowerShell
PS /home/vagrant> $Session

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  1 SSH1            192.168.33.210  RemoteMachine   Opened        DefaultShell             Available

Enter-PSSessionでWindowsへ接続できます。

# CentOS PowerShell
PS /home/vagrant> Enter-PSSession -Session $Session
[192.168.33.210]: PS C:\Users\Administrator\Documents>

ここでWindows側でPowerShell Coreが実行されていのですが、現時点ではまだ、PowerShell Core→PowerShell 4.0(Desktop)とネストしてPowerShellを対話的に実行できない様で、実際にやってみるとハングしてしまいます。

ただし、powershell.exe -Command {ほげ}の様にコマンド実行であればネストして実行可能ですので、以下の例の様にPowerShell Coreにないコマンドレット(Get-NetFirewallRule)を実行することもできます。

# CentOS PowerShell → Windows PowerShell Core

# コマンドの実行結果に日本語があるのでShift-JISを有効に
[192.168.33.210]: PS C:\> [System.Text.Encoding]::RegisterProvider([System.Text.CodePagesEncodingProvider]::Instance)
[192.168.33.210]: PS C:\> $OutputEncoding = [System.Text.Encoding]::GetEncoding(932)

# CentOS PowerShell → Windows PowerShell Core → Windows PowerShell 4.0
[192.168.33.210]: PS C:\> powershell -Command { Get-NetFirewallRule -DisplayName *ssh* }


Name                    : {b467a636-88e4-4478-a408-e43a87356821}
ID                      : {b467a636-88e4-4478-a408-e43a87356821}
Group                   :
Platform                : {}
LSM                     : False
Profile                 : Any
Caption                 :
Description             :
ElementName             : SSH
InstanceID              : {b467a636-88e4-4478-a408-e43a87356821}
CommonName              :
PolicyKeywords          :
Enabled                 : 1
PolicyDecisionStrategy  : 2
PolicyRoles             :
ConditionListType       : 3
CreationClassName       : MSFT|FW|FirewallRule|{b467a636-88e4-4478-a408-e43a87356821}
ExecutionStrategy       : 2
Mandatory               :
PolicyRuleName          :
Priority                :
RuleUsage               :
SequencedActions        : 3
SystemCreationClassName :
SystemName              :
Action                  : 2
Direction               : 1
DisplayGroup            :
DisplayName             : SSH
EdgeTraversalPolicy     : 0
EnforcementStatus       : {0}
LocalOnlyMapping        : False
LooseSourceMapping      : False
Owner                   :
Platforms               : {}
PolicyStoreSource       : PersistentStore
PolicyStoreSourceType   : 1
PrimaryStatus           : 1
Profiles                : 0
RuleGroup               :
Status                  : 規則は、ストアから正常に解析されました。
StatusCode              : 65536
PSComputerName          :

最後に

とりあえずこんな感じです。
WindowsからLinuxへのPSRemoting、なかなか胸が熱くなります。

実はWindowsからLinuxへPSRPを使用した接続も可能なのですが、まだバギーな部分が多い様で、このあたりについては別の機会にエントリを書こうと思います。

【2016/09/16追記】

続き書きました。

stknohg.hatenablog.jp

【2017/08/15追記】

Windows 10 Creators Updateでも使える様になっていたので別エントリを起こしました。

blog.shibata.tech