WIN1@Codename

Codename

Windowsの中には32bit版と64bit版のPowerShellがあります

VBやC#から、System.Management.Automation.Runspacesクラスを使ってPowerShellのコマンドを実行することができます。

参考:Visual StudioとPowerShellの良い関係 for Hyper-V

このとき、VisualStudioで特に何も設定指定な場合、仕様として32bit版のPowerShellが呼び出されています。

PowerShell.exeはWindows内に実は二つ存在し、32bit版と64bit版とでそれぞれ異なります。

64bit版 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

32bit版 C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe

どちらのPowerShellで動いているかを確認するには、コマンドプロンプトで [System.Environment]::Is64BitProcess と入力して、 Trueであれば64bit、Falseであれば32bitということになります。

PS > [System.Environment]::Is64BitProcess
True

VisualStudioでコンテナ関連のコマンドを呼び出していたとき、「コマンドが見つかりません。」とのエラーに遭遇しました。

このエラーはローカルのPowerShellに対してRunspaseを使って呼び出しを行うと発生して、リモートのPowerShellに対しては発生しないものです。

コンテナ関連のコマンドは、64bit版でのみ提供されているので、既定の設定でVisualStudioでコンパイルしたコードでは、32bit版のPwerShell.exeを呼び出してしまいエラーとなっていたのが原因です。

ローカルを呼び出す場合は32bitを、リモートは64bitという暗黙の設定がなされているようです。

回避方法としては、VisualStudioの方できっちりと対象のCPUを「AnyCPU」ではなく、「x64」でコンパイルしてください。

20161226050259

VBからPowerShellを実行する場合の、エラーの取得方法

VBからPowerShellを呼び出す場合には、「RunspaceInvoke 」を用いて実行しますが、その時のPowerShell側で発生したエラーの取得方法です。

RunspaceInvokeオブジェクトのInvokeメソッド実行時に、エラー内容をIList 型で取得できます。

あとは、エラーがある場合にこのオブジェクトを利用してエラー内容を表示することになります。

下記は、リモートから Get-VM2 という存在しないPowerShellコマンドをわざと実行して、エラーを表示しています。

PowerShellのリモート実行のサンプルコードも含まれていますので参考までに。

    1:          Dim strCmdlet As String = ""
   2:          strCmdlet += "$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'admin', (ConvertTo-SecureString 'adminpass' -AsPlainText -Force);"
   3:          strCmdlet += "Invoke-Command -ComputerName 'Server01' -Credential $Cred {"
   4:          strCmdlet += "Get-VM2 | Select Name"
   5:          strCmdlet += "}"
   6:   
   7:          Dim objRunspace As Runspace = RunspaceFactory.CreateRunspace()
   8:          objRunspace.Open()
   9:          Dim objRunspaceInvoke As RunspaceInvoke = New RunspaceInvoke(objRunspace)
  10:          Dim objErrors As IList = Nothing
  11:          Dim objResult As ObjectModel.Collection(Of PSObject) = objRunspaceInvoke.Invoke(strCmdlet, Nothing, objErrors)
  12:   
  13:          If objErrors.Count() > 0 Then
  14:              Dim objError As PSObject = objErrors(0)
  15:              Dim objRecord As ErrorRecord = objError.BaseObject
  16:              Console.WriteLine(objRecord.Exception.Message)
  17:              Console.WriteLine(objRecord.FullyQualifiedErrorId)
  18:          Else
  19:              For Each objPSObject As PSObject In objResult
  20:                  Console.WriteLine(objPSObject.Properties("Name").Value)
  21:              Next
  22:          End If

エラー内容はPowerShell実行時のエラーと同じ内容が取得できます。

用語 'Get-VM2' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。
名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
CommandNotFoundException

TechNet スクリプトセンター

ここで紹介しているHyper-V関連のVBScriptは「TechNet スクリプトセンター」でも紹介しています。

WIN1の他にもMVPの方々が参考になるスクリプトを多数紹介しています。

スクリプトセンター自体も数多くのこれは!と思えるようなサンプルが多数掲載せれていますので、是非是非ご利用ください。

スクリプトはPowerShell? WSH?

マイクロソフトのスクリプトセンター、
http://technet.microsoft.com/ja-jp/scriptcenter/

サンプルコードが世界中から投稿されていますが、スクリプトと呼ばれるものの定義としては「メモ帳などで簡単に作成編集できるもの」という感じでしょうか。

以前はバッチファイルとして、サーバー管理者などが定期的な処理作業を簡略化するために、コマンドを組み合わせたものを使用するのが一般的でした。

Windows Script Host(WSH)がWindows98に搭載されるようになると、Windows上の簡単な処理はVBScriptでメモ帳などを使用して簡単に作れるようになりました。

中には数MBにおよぶ膨大なスクリプトをみかけることもありますが、やはりスクリプトは手軽に簡単にがキーワードとなるようです。

最近では、スクリプトがWSHのほかにPowerShellを使用して作成される機会が増えてきたようです。

Windows制御のコマンドラインの集まりで、.NetFramework を利用できるのが最大の特徴ではないでしょうか。 VisualStudioでプログラムを書くほどではないけれども、WSHでは面倒な処理もPowerShellでは簡単にコードが書けるといったものがかなりあるようです。

ただ、あまりにもコマンドがありすぎて、お目当てのコマンドを探し出すのが結構大変な場合もあります。

TPOにあわせて、WSHとPowerShellを使い分けることでさらに効率的なスクリプト作成ができるようになりますね。

Html Copy

Visual Studio 2010の拡張機能である「Visual Studio 2010 Productivity Power Tools(Pro Power Tools)」にある「Html Copy」は便利です。

BlogにVisualStudioのコードを貼り付ける場合、色分けやタブ設定が結構面倒でした。
いままでは、コード変換ツールなど自分で作ってHTMLに変換していましたが、「Html Copy」は普通に Ctrl+C でコピーして、Blogに貼り付けるときに「形式を選択して貼り付け」にすると
20103323020717

こういったような選択画面が出てくるので、「書式の保持」 を選択するときちんと色分けやタブ設定された状態でコードが貼り付けられます。

20104023020715  VisualStudioのこのコードが

こんな感じに貼り付けられました。

  Function ConnectManagementScope(ByVal strServer As String, ByVal strAccount As String, ByVal strPassword As String) As ManagementScope
        Dim objConnectionOptions As New ConnectionOptions()
        objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate
        objConnectionOptions.EnablePrivileges = True
        objConnectionOptions.Username = strAccount
        objConnectionOptions.Password = strPassword
        Dim objManagementScope As New ManagementScope("\\" + strServer + "\root\virtualization", objConnectionOptions)
        objManagementScope.Connect()
        Return objManagementScope
    End Function
次のページ

FC2Ad