tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

Windows RTでのPowerShellへの制限

30/Mar/2013にあった、めとべやでのセッションでXingle先生が、PowerShellの限界とか、PowerShellダメ!! とか言われたので試しました。 いえ別にムキにはなっていませんし、Surface開けて真っ先にやったことがPowershellなんてこともありません。 ====

PowerShell ISEがない

アイスがないとか、なんてことでしょう……。 この時点でやる気が8割失われました。 でもps1が読めるっていうし……が、頑張る。 [office src="https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%21466&authkey=AH8yq3IjvnikzcE" width="318" height="179"] ちなみに、ProcessでPowerShell_ISEでもダメでした。

PowerShellをタスクバーにピン止め

当然です。やりましょう。

Set-ExecutionPolicyは可能

何はともあれ、新PCを手に入れたらやりましょう。 例の通り、管理者権限でPowerShellを起動します。

Set-ExecutionPolicy RemoteSigned

Enable-PSremotingは可能

これで、Windows RT端末に他のPowerShell使える端末からリモート操作ができます。 これも、管理者権限でPowerShellを起動します。

Enable-PSRemoting

Surfaceに繋ぐPCでTrustedHost設定も可能

管理者権限で、ClientがTurstするServerを設定をします。 これ、いまだに「なぜClientが信頼するServerを設定する」のか謎でしょうがないです。 これをしないと、対象のPCに手元のClient PCから接続できません。

winrm s winrm/config/client '@{TrustedHosts="*"}'

勿論Surface上で有効化も可能です。

コマンドレット数が制限されてる

さて、まずは何が出来ないのか見る前に、ざっくりとWindows 8とWindows RTとのコマンドレット数の違いから見ましょう。

OS Cmdlet数
Windows 8 Pro (No Module) 1396
Surface RT 869

Windows 8が、Document下の.\WindowsPowerShell\Modulesをリネームして読み込まないようにした状態です。 Windows RTは、購入直後10分ぐらいです。 [office src="https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%21516&authkey=AEEUUxMvbtFoXNM" width="319" height="212"] [office src="https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%21517&authkey=APOfS7pjQ4IU_FE" width="318" height="179"] 何のコマンドが無いのかを見ると、Invoke-Processを初めとしてちょろちょろ抜けています……なので、PowerShellからProcess実行は此処でも制限をかけようとしているようですね。

参照の追加はできるがインスタンスからメソッドが

参照の追加、コンパイルしてロードまでやってくれる便利な奴といえば、Add-Typeですね。 では、参照追加の必要な[System.Windows.Forms]を試しましょう。

Add-Type -AssembyName System.Windows.Forms

お、おぉ、追加できました。 [office src="https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%21520&authkey=APiwWoeNeV07mOY" width="318" height="179"] では、読めているかを確認してみて…

[System.Windows.Forms.MessageBox]

読めてます。 [office src="https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%21519&authkey=AI6ZRsq_L8d6LLA" width="318" height="179"] ではメソッドを呼び出そうとすると

[System.Windows.Forms.MessageBox]::Show("")
メソッドを呼び出せません。この言語モードでは、メソッドの呼び出しはコアの型のみでサポートされています。

[office src="https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%21521&authkey=ADXWrhV9-i_MZis" width="318" height="179"] 言語ですか……ふむ。

昔ながらのあれもだめ

今は亡きあれです、[Reflection.Assembly]を使ってみましょう。

[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

同じエラーではじかれます。

メソッドを呼び出せません。この言語モードでは、メソッドの呼び出しはコアの型のみでサポートされています。

ようはNew-Objectが許可されていない

つまり、New-Objectの時点でダメな訳です。

New-Object -ComObject Excel.Application
型を生成できません。この言語モードでは、メソッドの呼び出しはコアの型のみでサポートされています。

C# Definitionを直に読み込ませたらどう

誰もが考える方法です。

Add-Type -TypeDefinition "public class hogehoge {}"
型を追加できません。この言語モードでは、新しい方の定義はサポートされていません。

言語モードってどういうこと

これは、RunSpaceの言語モードを示します。

$host.Runspace.LanguageMode

通常、Windows 8などのx86/64 PCでは、次の言語モードです。

FullLanguage

これが、Windows RT, Surfaceではこうです。

ConstrainedLanguage

つまり言語モードが違うために出来ないわけですね。

セッションの言語モードを変えてみる

なら、Session中の言語をFull Languageに変えたらごまかされない?とやってみます。 セッションを作って。

$surface = New-PSSession -ComputerName surface

セッション成立を確認して

$surface

セッションに入って…これで、Surface上で操作となります。 Microsoft Account同志なのでGet-Credentialいらず ((

Enter-PSSession -Session $surface

Surface上で、PSSessionConfigurationを取得します。

[surface]: PS C:\Users\acquire\Documents> Get-PSSessionConfiguration | select *

結果です。

Architecture                  : 32
Filename                      : %windir%\system32\pwrshplugin.dll
ResourceUri                   : http://schemas.microsoft.com/powershell/microsoft.powershell
MaxConcurrentCommandsPerShell : 1000
Capability                    : {Shell}
xmlns                         : http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration
MaxConcurrentUsers            : 5
Name                          : microsoft.powershell
SupportsOptions               : true
ProcessIdleTimeoutSec         : 0
ExactMatch                    : False
RunAsUser                     :
IdleTimeoutms                 : 7200000
OutputBufferingMode           : Block
PSVersion                     : 3.0
SecurityDescriptorSddl        : O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxShellsPerUser              : 25
AutoRestart                   : false
MaxShells                     : 25
MaxIdleTimeoutms              : 2147483647
Uri                           : http://schemas.microsoft.com/powershell/microsoft.powershell
SDKVersion                    : 2
XmlRenderingType              : text
RunAsPassword                 :
MaxProcessesPerShell          : 15
ParentResourceUri             : http://schemas.microsoft.com/powershell/microsoft.powershell
Enabled                       : true
UseSharedProcess              : false
MaxMemoryPerShellMB           : 1024
lang                          : ja-JP
Permission                    : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Architecture                    : 32
Filename                        : %windir%\system32\pwrshplugin.dll
PSSessionConfigurationTypeName  : Microsoft.PowerShell.Workflow.PSWorkflowSessionConfiguration
MaxProcessesPerShell            : 15
MaxConcurrentCommandsPerShell   : 1000
PersistencePath                 : C:\Users\acquire\AppData\Local\Microsoft\Windows\PowerShell\WF\PS
Capability                      : {Shell}
AllowedActivity                 : {PSDefaultActivities}
xmlns                           : http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration
PersistWithEncryption           : False
MaxConcurrentUsers              : 5
RemoteNodeSessionIdleTimeoutSec : 60
Name                            : microsoft.powershell.workflow
OutOfProcessActivity            : {InlineScript}
SessionConfigurationData        :                              <SessionConfigurationData>
                                     <Param Name="ModulesToImport" Value="%windir%\system32\windowspowershell\v1.0\Modu
                                  les\PSWorkflow"/>                                 <Param Name="PrivateData">
                                                              <PrivateData>                                         <Pa
                                  ram Name="enablevalidation" Value="true" />                                     </Pri
                                  vateData>                                 </Param>                             </Sess
                                  ionConfigurationData>
MaxSessionsPerWorkflow          : 5
SupportsOptions                 : true
ProcessIdleTimeoutSec           : 28800
ExactMatch                      : False
RunAsUser                       :
IdleTimeoutms                   : 7200000
SessionThrottleLimit            : 100
OutputBufferingMode             : Block
MaxActivityProcesses            : 5
ResourceUri                     : http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
ActivityProcessIdleTimeoutSec   : 60
MaxPersistenceStoreSizeGB       : 10
SecurityDescriptorSddl          : O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxShellsPerUser                : 25
ModulesToImport                 : %windir%\system32\windowspowershell\v1.0\Modules\PSWorkflow
AutoRestart                     : false
MaxShells                       : 25
MaxConnectedSessions            : 100
MaxMemoryPerShellMB             : 1024
MaxIdleTimeoutms                : 2147483647
Uri                             : http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
SDKVersion                      : 2
XmlRenderingType                : text
RunAsPassword                   :
PSVersion                       : 3.0
ParentResourceUri               : http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
MaxRunningWorkflows             : 30
WorkflowShutdownTimeoutMSec     : 500
EnableValidation                : true
Enabled                         : true
UseSharedProcess                : true
MaxSessionsPerRemoteNode        : 5
MaxDisconnectedSessions         : 1000
AssemblyName                    : Microsoft.PowerShell.Workflow.ServiceCore, Version=3.0.0.0, Culture=neutral, PublicKe
                                  yToken=31bf3856ad364e35, processorArchitecture=MSIL
lang                            : ja-JP
Permission                      : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

新しいセッション設定をRT上で出します。

New-PSSessionConfigurationFile -Path .\default.pssc

取得できたファイルで、LanguageをFull Languageになっていることを確認します。 大丈夫ですね?

@{

# このセッション構成に使用されるスキーマのバージョン番号
SchemaVersion = '1.0.0.0'

# このセッション構成を一意に識別するために使用される ID。
GUID = 'c4d41614-4bf7-4ed8-951a-ff23963f14f2'

# このセッション構成の実行ポリシーを指定します
ExecutionPolicy = 'Restricted'

# このセッション構成の言語モードを指定します
LanguageMode = 'FullLanguage'

# このセッション構成の初期状態
SessionType = 'Default'

# このセッション構成で定義される環境変数
# EnvironmentVariables = 

# このセッション構成の作成者
Author = 'acquire'

# Company associated with this session configuration
CompanyName = '不明'

# このセッション構成の著作権情報
Copyright = '(c) 2013 acquire. All rights reserved.'

# このセッション構成の機能の説明
# Description = 

# このセッション構成で使用される Windows PowerShell エンジンのバージョン
# PowerShellVersion = 

# インポートされるモジュール。
# ModulesToImport = 

# このセッション構成で読み込まれるアセンブリ
# AssembliesToLoad = 

# このセッション構成で表示されるエイリアス
# VisibleAliases = 

# このセッション構成で表示されるコマンドレット
VisibleCmdlets = 'Get-*'

# このセッション構成で表示される関数
# VisibleFunctions = 

# このセッション構成で表示されるプロバイダー
# VisibleProviders = 

# このセッション構成で定義されるエイリアス
# AliasDefinitions = 

# このセッション構成で定義される関数
# FunctionDefinitions = 

# このセッション構成で定義される変数
# VariableDefinitions = 

# このセッション構成で読み込まれる型ファイル (.ps1xml)
# TypesToProcess = 

# このセッション構成で読み込まれる書式ファイル (.ps1xml)。
# FormatsToProcess = 

# セッションの構成後に実行するスクリプトを指定します
# ScriptsToProcess = 

}

Windows RT, Surface上でFull Languageな設定を読み込ませます。

Register-PSSessionConfiguration -Name "FullLanguage" -Path .\default.pssc

Language設定がFullLanguageになったことを確認します。

Get-PSSessionConfiguration | select *

なってます。

[Surface]: PS C:\Users\acquire\Desktop> Get-PSSessionConfiguration | select *


Copyright                     : (c) 2013 acquire. All rights reserved.
CompanyName                   : 不明
GUID                          : c4d41614-4bf7-4ed8-951a-ff23963f14f2
Author                        : acquire
VisibleCmdlets                : Get-*
SessionType                   : Default
ExecutionPolicy               : Restricted
SchemaVersion                 : 1.0.0.0
LanguageMode                  : FullLanguage
Architecture                  : 32
Filename                      : %windir%\system32\pwrshplugin.dll
ResourceUri                   : http://schemas.microsoft.com/powershell/FullLanguage
MaxConcurrentCommandsPerShell : 1000
Capability                    : {Shell}
xmlns                         : http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration
MaxConcurrentUsers            : 5
Name                          : FullLanguage
SupportsOptions               : true
ProcessIdleTimeoutSec         : 0
ExactMatch                    : true
ConfigFilePath                : C:\Windows\System32\WindowsPowerShell\v1.0\SessionConfig\FullLanguage_c4d41614-4bf7-4ed
                                8-951a-ff23963f14f2.pssc
RunAsUser                     :
IdleTimeoutms                 : 7200000
OutputBufferingMode           : Block
PSVersion                     : 3.0
SecurityDescriptorSddl        : O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxShellsPerUser              : 25
AutoRestart                   : false
MaxShells                     : 25
MaxIdleTimeoutms              : 43200000
Uri                           : http://schemas.microsoft.com/powershell/FullLanguage
SDKVersion                    : 2
XmlRenderingType              : text
RunAsPassword                 :
MaxProcessesPerShell          : 15
ParentResourceUri             : http://schemas.microsoft.com/powershell/FullLanguage
Enabled                       : True
UseSharedProcess              : false
MaxMemoryPerShellMB           : 1024
lang                          : ja-JP
Permission                    : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Architecture                  : 32
Filename                      : %windir%\system32\pwrshplugin.dll
ResourceUri                   : http://schemas.microsoft.com/powershell/microsoft.powershell
MaxConcurrentCommandsPerShell : 1000
Capability                    : {Shell}
xmlns                         : http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration
MaxConcurrentUsers            : 5
Name                          : microsoft.powershell
SupportsOptions               : true
ProcessIdleTimeoutSec         : 0
ExactMatch                    : False
RunAsUser                     :
IdleTimeoutms                 : 7200000
OutputBufferingMode           : Block
PSVersion                     : 3.0
SecurityDescriptorSddl        : O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxShellsPerUser              : 25
AutoRestart                   : false
MaxShells                     : 25
MaxIdleTimeoutms              : 2147483647
Uri                           : http://schemas.microsoft.com/powershell/microsoft.powershell
SDKVersion                    : 2
XmlRenderingType              : text
RunAsPassword                 :
MaxProcessesPerShell          : 15
ParentResourceUri             : http://schemas.microsoft.com/powershell/microsoft.powershell
Enabled                       : true
UseSharedProcess              : false
MaxMemoryPerShellMB           : 1024
lang                          : ja-JP
Permission                    : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Architecture                    : 32
Filename                        : %windir%\system32\pwrshplugin.dll
PSSessionConfigurationTypeName  : Microsoft.PowerShell.Workflow.PSWorkflowSessionConfiguration
MaxProcessesPerShell            : 15
MaxConcurrentCommandsPerShell   : 1000
PersistencePath                 : C:\Users\acquire\AppData\Local\Microsoft\Windows\PowerShell\WF\PS
Capability                      : {Shell}
AllowedActivity                 : {PSDefaultActivities}
xmlns                           : http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration
PersistWithEncryption           : False
MaxConcurrentUsers              : 5
RemoteNodeSessionIdleTimeoutSec : 60
Name                            : microsoft.powershell.workflow
OutOfProcessActivity            : {InlineScript}
SessionConfigurationData        :                              <SessionConfigurationData>
                                     <Param Name="ModulesToImport" Value="%windir%\system32\windowspowershell\v1.0\Modu
                                  les\PSWorkflow"/>                                 <Param Name="PrivateData">
                                                              <PrivateData>                                         <Pa
                                  ram Name="enablevalidation" Value="true" />                                     </Pri
                                  vateData>                                 </Param>                             </Sess
                                  ionConfigurationData>
MaxSessionsPerWorkflow          : 5
SupportsOptions                 : true
ProcessIdleTimeoutSec           : 28800
ExactMatch                      : False
RunAsUser                       :
IdleTimeoutms                   : 7200000
SessionThrottleLimit            : 100
OutputBufferingMode             : Block
MaxActivityProcesses            : 5
ResourceUri                     : http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
ActivityProcessIdleTimeoutSec   : 60
MaxPersistenceStoreSizeGB       : 10
SecurityDescriptorSddl          : O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxShellsPerUser                : 25
ModulesToImport                 : %windir%\system32\windowspowershell\v1.0\Modules\PSWorkflow
AutoRestart                     : false
MaxShells                       : 25
MaxConnectedSessions            : 100
MaxMemoryPerShellMB             : 1024
MaxIdleTimeoutms                : 2147483647
Uri                             : http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
SDKVersion                      : 2
XmlRenderingType                : text
RunAsPassword                   :
PSVersion                       : 3.0
ParentResourceUri               : http://schemas.microsoft.com/powershell/microsoft.powershell.workflow
MaxRunningWorkflows             : 30
WorkflowShutdownTimeoutMSec     : 500
EnableValidation                : true
Enabled                         : true
UseSharedProcess                : true
MaxSessionsPerRemoteNode        : 5
MaxDisconnectedSessions         : 1000
AssemblyName                    : Microsoft.PowerShell.Workflow.ServiceCore, Version=3.0.0.0, Culture=neutral, PublicKe
                                  yToken=31bf3856ad364e35, processorArchitecture=MSIL
lang                            : ja-JP
Permission                      : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

もう一回Add-Typeを試しましょう。

Add-Type -Assem System.web

メソッド呼び出しです。

[System.Web.Httputility]::UrlEncode("ああり",[System.Text.Encoding]::default)

ぐぬぬ……だめでした…

メソッドを呼び出せません。この言語モードでは、メソッドの呼び出しはコアの型のみでサポートされています。
発生場所 行:1 文字:1
+ [System.Web.Httputility]::UrlEncode("ああり",[System.Text.Encoding]::default)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) []、RuntimeException
    + FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage

懲りずに、System.Windows.Formsでやるも

Add-Type -Assem System.Windows.Forms

ここまでは前回と一緒。

[System.Windows.Forms.MessageBox]

で、ダメ

[System.Windows.Forms.MessageBox]::Show("")
メソッドを呼び出せません。この言語モードでは、メソッドの呼び出しはコアの型のみでサポートされています。
発生場所 行:1 文字:1
+ [System.Windows.Forms.MessageBox]::Show("")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) []、RuntimeException
    + FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage

制限まとめ

残念この上ないのですが、Windows RTは、.NETとPowerShell両面でがちがちに固められています。 が、PowerShell側は、言語を騙せればイケそうですね (( つまりこれらが原因です。

  1. 既定のRunSpaceにおける言語($host.Runspace.LanguageMode)が、ConstrainedLanguageになっているため、多くの.NETやいくつかのCmdletに接続制限が掛かっている。
  2. Microsoftの署名なしのソースを、コンパイル/読み込みできない。 これによりAdd-Typeでの定義、dll読み込みが禁止されています。

あ、VBSやCOMがダメなのは見てのとおりです。

Windows RT上でのPowerShell

PowerShell純正コマンドレット800余りで頑張りましょう。 .ps1は読めましたので。 あと、Get-CIMClassはイケたのでWMIは触れそうです。