30/Mar/2013にあった、めとべやでのセッションでXingle先生が、PowerShellの限界とか、PowerShellダメ!! とか言われたので試しました。 別にムキにはなっていませんし、Surface開けて真っ先にやったことがPowershellなんてこともありません。
PowerShell ISEがない
ISEがないとか、なんてことでしょう。 この時点でやる気が8割失われました。 でもps1が読めるっていうし……が、頑張る。 ちなみに、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分ぐらいです。
何のコマンドが無いのかを見ると、Invoke-Processを初めとしてちょろちょろ抜けています……なので、PowerShellからProcess実行は此処でも制限をかけようとしているようですね。
参照の追加はできるがインスタンスからメソッドが
参照の追加、コンパイルしてロードまでやってくれる便利な奴といえば、Add-Typeですね。 では、参照追加の必要な[System.Windows.Forms]を試しましょう。
Add-Type -AssembyName System.Windows.Forms
追加できました。では、読めているかを確認してみて…
[System.Windows.Forms.MessageBox]
読めてます。 ではメソッドを呼び出そうとすると
[System.Windows.Forms.MessageBox]::Show("")
メソッドを呼び出せません。この言語モードでは、メソッドの呼び出しはコアの型のみでサポートされています。
昔ながらのあれもだめ
今は亡きあれです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
つまり言語モードが違うために出来ないわけですね。
セッションの言語モードを変えてみる
なら、セッション中の言語を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
もう1回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側は、言語を騙せればイケそうです。つまりこれらが原因です。
- デフォルトのRunSpaceにおける言語($host.Runspace.LanguageMode)が、ConstrainedLanguageになっているため、多くの.NETやいくつかのCmdletに接続制限が掛かっている
- Microsoftの署名なしのソースを、コンパイル/読み込みできない。 これによりAdd-Typeでの定義、dll読み込みが禁止されている
VBSやCOMがダメなのは見てのとおりです。
Windows RT上でのPowerShell
PowerShell純正コマンドレット800余りで頑張りましょう。 .ps1は読めましたので。 あと、Get-CIMClassはイケたのでWMIは触れそうです。