{"id":2061,"date":"2013-10-01T15:42:31","date_gmt":"2013-10-01T15:42:31","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2013\/10\/01\/paap-windows-powershell-as-a-platform-part-1\/"},"modified":"2019-02-18T13:05:31","modified_gmt":"2019-02-18T20:05:31","slug":"paap-windows-powershell-as-a-platform-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/paap-windows-powershell-as-a-platform-part-1\/","title":{"rendered":"PaaP: Windows PowerShell as a Platform \u2013 Part 1"},"content":{"rendered":"<p align=\"justify\">In addition to being a scripting language, Windows PowerShell is also used as a platform in many applications. This is possible because the Windows PowerShell engine can be hosted inside an application. This blog post and the next will deal with the various APIs available for hosting Windows PowerShell in a C# application. <\/p>\n<p align=\"justify\">The most important type for hosting Windows PowerShell is the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/system.management.automation.powershell(v=vs.85).aspx\"><font color=\"#0080c0\">System.Management.Automation.PowerShell<\/font><\/a> class. This class provides methods that create a pipeline of commands and then execute those commands in a runspace. <\/p>\n<h4>AddCommand<\/h4>\n<p align=\"justify\">Let&#8217;s take a very simple example. Suppose you want to get the list of running processes on the machine. The way to run this command is as follows.<\/p>\n<p>Step 1 \u2013 Create a PowerShell object <\/p>\n<blockquote>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell ps = PowerShell.Create();<\/pre>\n<\/blockquote>\n<p>Step 2 \u2013 Add the command that you want to execute<\/p>\n<blockquote>\n<pre class=\"brush: powershell; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">ps.AddCommand(\u201cGet-Process\u201d);<\/pre>\n<\/blockquote>\n<p>Step 3 \u2013 Invoke the command<\/p>\n<blockquote>\n<pre class=\"brush: powershell; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">ps.Invoke();<\/pre>\n<\/blockquote>\n<p>You can also do all of those in a single step like this:<\/p>\n<blockquote>\n<pre class=\"brush: powershell; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell.Create().AddCommand(\u201cGet-Process\u201d).Invoke();<\/pre>\n<\/blockquote>\n<h4>AddParameter<\/h4>\n<p align=\"justify\">The previous example executes a single command without any parameters. Let\u2019s say I want to get a list of all the PowerShell processes running on the machine. I can use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/system.management.automation.powershell.addparameter(v=vs.85).aspx\">AddParameter<\/a> method to add parameters to the command.<\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell.Create().AddCommand(\u201cGet-Process\u201d)\n                   .AddParameter(\u201cName\u201d, \u201cPowerShell\u201d)\n                   .Invoke();<\/pre>\n<p align=\"justify\">To add more parameters, you can call AddParameter again like this: <\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell.Create().AddCommand(\u201cGet-Process\u201d)\n                   .AddParameter(\u201cName\u201d, \u201cPowerShell\u201d)\n                   .AddParameter(\u201cId\u201d, \u201c12768\u201d)\n                   .Invoke();<\/pre>\n<p align=\"justify\">Or, if you have a dictionary of parameter names and values, you can use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/system.management.automation.powershell.addparameters(v=vs.85).aspx\">AddParameters<\/a> method to add all the parameters. <\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">IDictionary parameters = new Dictionary&lt;String, String&gt;();\n<\/pre>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">parameters.Add(&quot;Name&quot;, &quot;PowerShell&quot;);\n\nparameters.Add(&quot;Id&quot;, &quot;12768&quot;);<\/pre>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell.Create().AddCommand(\u201cGet-Process\u201d)\n\t\t   .AddParameters(parameters)\n   \t\t   .Invoke()<\/pre>\n<h4>AddStatement<\/h4>\n<p align=\"justify\">Now that we have executed a single command and its parameters, let\u2019s execute a bunch of commands. The PowerShell API provides a way for us to simulate batching with the use of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/system.management.automation.powershell.addstatement(v=vs.85).aspx\">AddStatement<\/a> method, which adds an additional statement to the end of the pipeline. To get the list of running PowerShell processes, and then get the list of running services, do the following:<\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell ps = PowerShell.Create();\nps.AddCommand(\u201cGet-Process\u201d).AddParameter(\u201cName\u201d, \u201cPowerShell\u201d);\nps.AddStatement().AddCommand(\u201cGet-Service\u201d);\nps.Invoke();<\/pre>\n<h4>AddScript<\/h4>\n<p align=\"justify\">The AddCommand method only run commands. If I want to run a script, I can use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/system.management.automation.powershell.addscript(v=vs.85).aspx\">AddScript<\/a> method. Let&#8217;s assume I have a simple script, a.ps1, that gets the number of running PowerShell processes on my machine. <\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">------------D:\\PshTemp\\a.ps1----------\n$a = Get-Process -Name PowerShell\n$a.count\n------------D:\\PshTemp\\a.ps1----------\n<\/pre>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell ps = PowerShell.Create();\nps.AddScript(\u201cD:\\PshTemp\\a.ps1\u201d).Invoke();<\/pre>\n<p align=\"justify\">The AddScript API also provides an option to run the script in local scope. In this example, the script runs in local scope because we pass a value of <b>true<\/b> to the <b>useLocalScope<\/b> parameter. <\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell ps = PowerShell.Create();\nps.AddScript(@\u201cD:\\PshTemp\\a.ps1\u201d, true).Invoke();<\/pre>\n<h4>Handling Errors, Verbose, Warning, Debug and Progress Messages<\/h4>\n<p align=\"justify\">The PowerShell API also gives us access to the errors, verbose messages, etc. that are generated when the command runs. You can access the PowerShell.Streams.Error property to get the list of all errors and the PowerShell.Streams.Verbose property to get the verbose messages. There are properties for accessing the Progress, Debug and Warning messages as well. <\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">PowerShell ps = PowerShell.Create()\n                          .AddCommand(&quot;Get-Process&quot;)\n                          .AddParameter(&quot;Name&quot;, &quot;Non-ExistentProcess&quot;);\nps.Invoke();<\/pre>\n<p align=\"justify\">ps.Streams.Error has the list of errors that were generated when running this command. In our case, we get one error for looking for a non-existent process.<\/p>\n<pre class=\"brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;\">Get-Process : Cannot find a process with the name &quot;Non-ExistentProcess&quot;. \nVerify the process name and call the cmdlet again. \n+ CategoryInfo : ObjectNotFound: (Non-ExistentProcess:String) [Get-Process], \nProcessCommandException \n+ FullyQualifiedErrorId : \nNoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand<\/pre>\n<p align=\"justify\">The PowerShell API is very powerful. It enables us to execute the commands in synchronous\/asynchronous mode, to create a constrained runspace which exposes a limited set of commands, to execute commands in a nested pipeline, etc. <\/p>\n<p align=\"justify\">In all of the examples in this post, we created a default runspace that includes all of the built-in Windows PowerShell commands. This is not efficient in terms of the amount of memory consumed. In a lot of scenarios, people want to use a runspace with only a specific set of commands\/language elements. In the next blog post, I&#8217;ll explain how to create a more limited and efficient runspace. <\/p>\n<\/p>\n<p>Thanks, <\/p>\n<p>Indhu Sivaramakrishnan [MSFT] \n  <br \/> Windows PowerShell Developer <\/p>\n<p> Microsoft Corporation<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In addition to being a scripting language, Windows PowerShell is also used as a platform in many applications. This is possible because the Windows PowerShell engine can be hosted inside an application. This blog post and the next will deal with the various APIs available for hosting Windows PowerShell in a C# application. The most [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2061","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>In addition to being a scripting language, Windows PowerShell is also used as a platform in many applications. This is possible because the Windows PowerShell engine can be hosted inside an application. This blog post and the next will deal with the various APIs available for hosting Windows PowerShell in a C# application. The most [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/2061","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=2061"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/2061\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=2061"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=2061"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=2061"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}