Amazon FSx for Windows File Server のリモートPowerShellコンソールの制限について

2021.02.19

しばたです。

前の記事でも触れましたが、Amazon FSx for Windows File Server(以後 FSx for Windows)では一部の設定にPowerShell Remotingを使う必要があります。

PowerShell Remotingを使った管理方法としては以下の二種類の方法があります。

  • Invoke-Commandを使い、管理コマンドをリモート実行して直ちに終了する
  • Enter-PSSessionを使い、PowerShellエンドポイントにログオンしリモートの対話コンソールを使用する

このうち後者については、簡単に言ってしまえばFSx for Windowsの実体となるWindows Serverにログインする形となるためコンソールで利用できる機能がかなり制限されています。

本記事ではこの制限について解説します。

はじめに

FSx for WindowsでPowerShell Remotingを使う場合は専用のエンドポイントに接続する必要があるため-ConfigurationNameパラメーターにFSxRemoteAdminを指定する必要があります。
また既知の不具合対応のため言語ロケールを英語にしておく必要もあります。

Enter-PSSessionで対話コンソールを使う場合は以下の様にパラメーターを指定して接続します。

#
# PowerShell RemotingでFSxに接続
#

# 管理者ユーザーで実行する場合はこんな感じ
$params = @{
    ComputerName = '<your PowerShell endpoint FQDN>'
    ConfigurationName = 'FSxRemoteAdmin'
    SessionOption = (New-PSSessionOption -UICulture 'en-US')
}
Enter-PSSession @params

# 認証情報を明示する場合はこんな感じ
$cred = Get-Credential '<your FSx admin user UPN>'
$params = @{
    ComputerName = '<your PowerShell endpoint FQDN>'
    Credential = $cred
    ConfigurationName = 'FSxRemoteAdmin'
    SessionOption = (New-PSSessionOption -UICulture 'en-US')
}
Enter-PSSession @params

無事接続すると下図の様な感じになります。

制限1. 言語モード

ここからコンソールの制限について触れていきます。

第一にFSx for Windowsのリモートコンソールでは変数の定義やオブジェクトのプロパティアクセスといった基本的な操作ができません。

(変数定義するとエラー)

(プロパティアクセスするとエラー)

これはPowerShellの言語モードが制限されているためです。

あまりメジャーでないのですがPowerShellにはセキュリティおよび統制上の制限をかけるために言語モードと呼ばれる機能が存在します。

言語モードの詳細は上記ドキュメントを参照していただきたいのですが、PowerShellにはざっくり4つのモードがあり下に行くほど機能が制限されるとお考えください。

言語モード 制限 備考
FullLanguage なし 通常のモード
ConstrainedLanguage 弱めの制限 PowerShell 3.0から導入
RestrictedLanguage 強めの制限
NoLanguage 極めて強い制限

FSx for Windowsのリモートコンソールがどの言語モードかは公開されていないのですが、挙動から推測するに「RestrictedLanguageモード」の様です。

RestrictedLanguageモードでは以下の制限が課せられています。

  • コマンド(Cmdlet、関数、CIM コマンド、ワークフロー)を実行できるがスクリプトブロックは使用できない
  • 以下の特殊変数のみ参照可能
    • $PSCulture, $PSUICulture, $true, $false, $null
  • 以下の演算子のみ使用可能
    • -eq, -gt, -lt
  • 代入、プロパティアクセス、メソッドの呼び出しは不可

制限2. 利用可能コマンド

FSx for WindowsのリモートコンソールではGet-Commandコマンドレットを使い利用可能なコマンドの一覧を取得できます。

PS>Get-Command

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Block-FSxSmbShareAccess                            1.0        FSxRemoteAdmin
Function        Clear-Host
Function        Close-FSxSmbOpenFile                               1.0        FSxRemoteAdmin
Function        Close-FSxSmbSession                                1.0        FSxRemoteAdmin
Function        Disable-FSxDedup                                   1.0        FSxRemoteAdmin
Function        Disable-FSxUserQuotas                              1.0        FSxRemoteAdmin
Function        Enable-FSxDedup                                    1.0        FSxRemoteAdmin
Function        Enable-FSxUserQuotas                               1.0        FSxRemoteAdmin
Function        Exit-PSSession
Function        Get-Command
Function        Get-FormatData
Function        Get-FSxDedupConfiguration                          1.0        FSxRemoteAdmin
Function        Get-FSxDedupJob                                    1.0        FSxRemoteAdmin
Function        Get-FSxDedupMetadata                               1.0        FSxRemoteAdmin
Function        Get-FSxDedupSchedule                               1.0        FSxRemoteAdmin
Function        Get-FSxDedupStatus                                 1.0        FSxRemoteAdmin
Function        Get-FSxShadowCopies                                1.0        FSxRemoteAdmin
Function        Get-FSxShadowCopySchedule                          1.0        FSxRemoteAdmin
Function        Get-FSxShadowStorage                               1.0        FSxRemoteAdmin
Function        Get-FSxSmbOpenFile                                 1.0        FSxRemoteAdmin
Function        Get-FSxSmbServerConfiguration                      1.0        FSxRemoteAdmin
Function        Get-FSxSmbSession                                  1.0        FSxRemoteAdmin
Function        Get-FSxSmbShare                                    1.0        FSxRemoteAdmin
Function        Get-FSxSmbShareAccess                              1.0        FSxRemoteAdmin
Function        Get-FSxUserQuotaEntries                            1.0        FSxRemoteAdmin
Function        Get-FSxUserQuotaSettings                           1.0        FSxRemoteAdmin
Function        Get-Help
Function        Grant-FSxSmbShareAccess                            1.0        FSxRemoteAdmin
Function        Measure-FSxDedupFileMetadata                       1.0        FSxRemoteAdmin
Function        Measure-Object
Function        New-FSxDedupSchedule                               1.0        FSxRemoteAdmin
Function        New-FSxShadowCopy                                  1.0        FSxRemoteAdmin
Function        New-FSxSmbShare                                    1.0        FSxRemoteAdmin
Function        Out-Default
Function        Remove-FSxDedupSchedule                            1.0        FSxRemoteAdmin
Function        Remove-FSxShadowCopies                             1.0        FSxRemoteAdmin
Function        Remove-FSxShadowCopySchedule                       1.0        FSxRemoteAdmin
Function        Remove-FSxShadowStorage                            1.0        FSxRemoteAdmin
Function        Remove-FSxSmbShare                                 1.0        FSxRemoteAdmin
Function        Revoke-FSxSmbShareAccess                           1.0        FSxRemoteAdmin
Function        Select-Object
Function        Set-FSxDedupConfiguration                          1.0        FSxRemoteAdmin
Function        Set-FSxDedupSchedule                               1.0        FSxRemoteAdmin
Function        Set-FSxShadowCopySchedule                          1.0        FSxRemoteAdmin
Function        Set-FSxShadowStorage                               1.0        FSxRemoteAdmin
Function        Set-FSxSmbServerConfiguration                      1.0        FSxRemoteAdmin
Function        Set-FSxSmbShare                                    1.0        FSxRemoteAdmin
Function        Set-FSxUserQuotas                                  1.0        FSxRemoteAdmin
Function        Stop-FSxDedupJob                                   1.0        FSxRemoteAdmin
Function        Unblock-FSxSmbShareAccess                          1.0        FSxRemoteAdmin
Function        Update-FSxDedupStatus                              1.0        FSxRemoteAdmin

ぱっと見たくさんある様に思えますが、ほとんどがFSx for Windows管理用のコマンドであり、それ以外では

  • Clear-Host (clear)
  • Exit-PSSession (exit)
  • Get-Command (gcm)
  • Measure-Object (measure)
  • Select-Object (select)

しか使えません。
(Get-FormatDataOut-DefaultはPowerShell内部用です。Get-Helpは定義されているものの実行するとエラーになります)

実行可能なコマンド自体が極めて少ない上、Select-Objectに至っては通常のコマンドレットではなくカスタマイズされたもので、特定のプロパティのみ選択可能とさらに制限されています。

Cannot validate argument on parameter 'Property'. The argument "Description" does not belong to the set "ModuleName,Namespace,OutputType,Count,HelpUri,Name,CommandType,ResolvedCommandName,DefaultParameterSet,CmdletBinding,Parameters" specified by the ValidateSet attribute.

上記エラーメッセージから分かる様にFSxコンソールのSelect-Object

  • ModuleName
  • Namespace
  • OutputType
  • Count
  • HelpUri
  • Name
  • CommandType
  • ResolvedCommandName
  • DefaultParameterSet
  • CmdletBinding
  • Parameters

プロパティのみ指定可能となっています。

なんとかインチキできんのか?

ここまでの説明でFSx for WindowsのリモートPowerShellコンソールがガチガチに制限されているのがお分かりいただけたかと思います。
セキュリティの都合制限を掛ける必要があるのは理解できますがここまで制限されてしまうと率直に言って不便で仕方ありません。

FSx for Windowsのリモート管理で複雑なことをしたい場合はリモートコンソールを使わずにInvoke-Commandでリモートからオブジェクトを取得して制限のないローカルコンソールで処理するのをおススメします。

たとえば、FSx for Windowsの共有フォルダの詳細を取得するにはGet-FSxSmbShareを使いますが、リモートコンソール上では個別のプロパティを取得できませんが、Invoke-Commandを使い以下の様にすれば全情報を取得することが可能です。

# Get-FSxSmbShare の結果をローカルで Select-Object する
# ※ローカルの Select-Object は制限されていない
$cred = Get-Credential '<your FSx admin user UPN>'
$params = @{
    ComputerName = '<your PowerShell endpoint FQDN>'
    Credential = $cred
    ScriptBlock = {
        # ここにリモートで実行するコマンドを記述
        Get-FSxSmbShare 
    }
    ConfigurationName = 'FSxRemoteAdmin'
    SessionOption = (New-PSSessionOption -UICulture 'en-US')
}
Invoke-Command @params | Select-Object Name, Path, ShareType, FolderEnumerationMode

もちろんInvoke-Commandの結果を変数に代入したり、ForEach-Objectと組み合わせてより複雑な処理を実行することもできます。

# ForEach-Object を使えばもっと複雑な処理もできる
$cred = Get-Credential '<your FSx admin user UPN>'
$params = @{
    ComputerName = '<your PowerShell endpoint FQDN>'
    Credential = $cred
    ScriptBlock = {
        # ここにリモートで実行するコマンドを記述
        Get-FSxSmbShare 
    }
    ConfigurationName = 'FSxRemoteAdmin'
    SessionOption = (New-PSSessionOption -UICulture 'en-US')
}
Invoke-Command @params | ForEach-Object {
    # ここにローカルで実行する処理を記述
    # $_ には Get-FSxSmbShare の結果がリモートから渡ってくる
    $_ | Select-Object Name, Path, ShareType, FolderEnumerationMode
    #
    # ※実際にはよしなに複雑な処理を書いてください
    #
}

リモートで実行される処理とローカルで実行される処理を常に意識ないといけない面倒さはありますが、リモートコンソールの制限による不便さはほとんど解消されると思います。

最後に

以上となります。

そもそもFSx for Windowsのリモート管理をする人がそんなにいないせいか、このあたりの制限についてはAWSのドキュメントにも全然記載されていません。
初見では絶対にハマるポイントだと思いますので本記事の内容が誰かの役に立てば幸いです。