Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Calling PowerShell from CSharp

227313c3533b7f887e1eccb63a291b23?s=47 tanaka_733
December 21, 2013

Calling PowerShell from CSharp

第1回PowerShell勉強会で話した資料です

227313c3533b7f887e1eccb63a291b23?s=128

tanaka_733

December 21, 2013
Tweet

More Decks by tanaka_733

Other Decks in Technology

Transcript

  1. None
  2. 仕事 個人 http://tech.tanaka733.net http://www.buildinsider.net/web/iis8

  3. PowerShell そのものの内容は薄いです。たぶん。予定は未定 PowerShell をC# から実行したい! • C# というか .NET Framework

    からですが、コードはC# のみです • 通常の外部プロセス実行だと落とし穴が • コマンドパイプラインも使いたい • リモートコンピューターにも実行したい 最後におまけが!? 資料と出てくるソースコードは今日中に公開します
  4. None
  5. https://speakerdeck.com/tanaka733/bokufalsekao-etage- topu-tong-c-nadepuroizhan-lue

  6. None
  7. None
  8. None
  9. static void Main(string[] args) { var psInfo = new ProcessStartInfo

    { FileName = "powershell.exe", CreateNoWindow = true, UseShellExecute = false, Arguments = "Get-ChildItem", RedirectStandardOutput = true }; var p = Process.Start(psInfo); Console.WriteLine(p.StandardOutput.ReadToEndAsync().Result); Console.ReadKey(); }
  10. None
  11. None
  12. DEMO

  13. using (var rs = RunspaceFactory.CreateRunspace()) { rs.Open(); using (var ps

    = PowerShell.Create()) { ps.Runspace = rs; ps.AddCommand("Get-Service"); ps.Invoke() .Select(result => string.Format("{0} {1}", result.Properties["Status"].Value, result.Properties["Name"].Value)) .ToList() .ForEach(Console.WriteLine); } }
  14. using (var rs = RunspaceFactory.CreateRunspace()) { rs.Open(); using (var ps

    = PowerShell.Create()) { ps.Runspace = rs; ps.AddCommand("Get-Service"); ps.Invoke() .Select(result => string.Format("{0} {1}", result.Properties["Status"].Value, result.Properties["Name"].Value)) .ToList() .ForEach(Console.WriteLine); } }
  15. //これでもプロパティ取得できます ps.Invoke() .Select(result => result.BaseObject) .Cast<dynamic>() .Select(result => string.Format("{0} {1}",

    result.Status, result.ServiceName)) .ToList() .ForEach(Console.WriteLine);
  16. None
  17. None
  18. DEMO

  19. using (var ps = PowerShell.Create()) { ps.Runspace = rs; ps.AddCommand("Get-Process");

    ps.AddArgument("chrome"); ps.AddCommand("Sort-Object"); ps.AddParameter("Descending"); ps.AddArgument("CPU"); var results = ps.Invoke(); results.Select(result => string.Format("{0} {1} {2}", result.Properties["Id"].Value, result.Properties["ProcessName"].Value, result.Members["CPU"].Value)) .ToList() .ForEach(Console.WriteLine); }
  20. None
  21. None
  22. http://msdn.microsoft.com/ja- jp/library/system.management.automation.psmembertypes(v=vs.8 5).aspx

  23. http://msdn.microsoft.com/ja- jp/library/system.management.automation.runspaces.runsp ace.defaultrunspace(v=vs.85).aspx using (var rs = RunspaceFactory.CreateRunspace()) { //

    これが必要※1 Runspace.DefaultRunspace = rs; rs.Open(); using (var ps = PowerShell.Create()) { ps.Runspace = rs;
  24. //これでもプロパティ取得できます results.Select(result => result.BaseObject) .Cast<Process>() .Select(result => string.Format("{0} {1} {2}",

    result.Id, result.ProcessName, result.TotalProcessorTime.TotalSeconds)) .ToList() .ForEach(Console.WriteLine);
  25. None
  26. None
  27. アプリ(powershell.exe, PowerShell ISE, あなたのアプリ)

  28. None
  29. DEMO

  30. None
  31. None
  32. DEMO

  33. var connectionInfo = new WSManConnectionInfo() { Scheme = "https", ComputerName

    = "servername.cloudapp.net", Port = 7654, Credential = new PSCredential("username", "syoboipassword".Aggregate( new SecureString(), (s, c) => { s.AppendChar(c); return s; })), SkipCACheck = true }; using (var rs = RunspaceFactory.CreateRunspace(connectionInfo)) {//以下略
  34. None
  35. None
  36. //connectionInfoは同じ using (var rsPool = RunspaceFactory.CreateRunspacePool(1, 2, connectionInfo)) { rsPool.Open();

    var gpsCommand = PowerShell.Create().AddCommand("Get-Process"); gpsCommand.RunspacePool = rsPool; var gpsCommandAsyncResult = gpsCommand.BeginInvoke(); var getServiceCommand = PowerShell.Create().AddCommand("Get-Service"); getServiceCommand.RunspacePool = rsPool; var getServiceCommandAsyncResult = getServiceCommand.BeginInvoke(); var gpsCommandOutput = gpsCommand.EndInvoke(gpsCommandAsyncResult); //出力は省略 var getServiceCommandOutput = getServiceCommand.EndInvoke(getServiceCommandAsyncResult); //出力は省略 rsPool.Close(); }
  37. DEMO

  38. None
  39. None
  40. None
  41. None
  42. $source = @" using System; //中略 public class Program {

    //[STAThread] <= 昔は必要だったらしいけど、v3かv4からいらなくなった (デフォルトSTA) public static void Run(string xaml) { var app = new Application(); var window = (Window)XamlReader.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml))); app.Run(window); } } "@ Add-Type -ReferencedAssemblies $assemblies ` -TypeDefinition $source -Language Csharp [Program]::Run($xaml)
  43. $assemblies = ( "System", "PresentationCore", "PresentationFramework", "System.Windows.Presentation", "System.Xaml", "WindowsBase", "System.Xml"

    )
  44. $xaml = @" <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title=“XamClaudiaPS1" Height="350" Width="525"> <Window.Resources>

    <!– 中略 --> </Window.Resources> <Grid> <!– 中略 --> </Grid> </Window> "@ https://github.com/Grabacr07/XamClaudia
  45. $signature = @" [DllImport("kernel32.dll", SetLastError = true)] public static extern

    Boolean GetSystemPowerStatus(out SystemPowerStatus sps); public struct SystemPowerStatus { public Byte ACLineStatus; public Byte BatteryFlag; public Byte BatteryLifePercent; public Byte Reserved1; public Int32 BatteryLifeTime; public Int32 BatteryFullLifeTime; } "@ Add-Type -MemberDefinition $signature -Name PowerStatus -Namespace PowerStatus $systemPowerStatus = New-Object PowerStatus.PowerStatus+SystemPowerStatus [void][PowerStatus.PowerStatus]::GetSystemPowerStatus([ref]$systemPowerStatus) $systemPowerStatus
  46. None
  47. None
  48. http://msdn.microsoft.com/en-us/library/ee706563(v=vs.85).aspx https://github.com/tanaka-takayoshi/PowerShellFromCsharp https://gist.github.com/tanaka-takayoshi/8066817 https://gist.github.com/tanaka-takayoshi/8066824

  49. await

  50. using

  51. None