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

Calling PowerShell from CSharp

tanaka_733
December 21, 2013

Calling PowerShell from CSharp

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

tanaka_733

December 21, 2013
Tweet

More Decks by tanaka_733

Other Decks in Technology

Transcript

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

    からですが、コードはC# のみです • 通常の外部プロセス実行だと落とし穴が • コマンドパイプラインも使いたい • リモートコンピューターにも実行したい 最後におまけが!? 資料と出てくるソースコードは今日中に公開します
  2. 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(); }
  3. 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); } }
  4. 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); } }
  5. 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); }
  6. 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;
  7. //これでもプロパティ取得できます 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);
  8. 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)) {//以下略
  9. //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(); }
  10. $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)
  11. $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