{"id":6824,"date":"2014-04-30T11:53:19","date_gmt":"2014-04-30T09:53:19","guid":{"rendered":"https:\/\/ingmarverheij.com\/?p=6824"},"modified":"2014-04-30T20:52:53","modified_gmt":"2014-04-30T18:52:53","slug":"run-and-compile-net-code-in-res-workspace-manager-using-powershell","status":"publish","type":"post","link":"https:\/\/ingmarverheij.com\/en\/run-and-compile-net-code-in-res-workspace-manager-using-powershell\/","title":{"rendered":"Run and compile .NET code in RES Workspace Manager (using PowerShell)"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 5px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Microsoft-.NET_.png\" alt=\"\" width=\"150\" height=\"143\" align=\"right\" border=\"0\" \/>There are occasions where you need a custom solution to fulfill a requirement which cannot be solved with existing applications or tools. This is usually where scripting comes into the picture, nowadays we tend to built most scripts using Microsoft PowerShell as it\u2019s a very powerful framework with a huge repository of cmdlets. Nonetheless there are situation where PowerShell has no built-in cmdlet (or third party cmdlet is available) and you\u2019d have to revert to API\u2019s or .NET code.<\/p>\n<p>Wouldn\u2019t it be a shame if you\u2019d have to write and compile .NET code using an IDE like Visual Studio before you can use that code? Well, there\u2019s a solution!<\/p>\n<p><!--more--><\/p>\n<h1>Common Intermediate Language<\/h1>\n<p><em>\u201cWindows PowerShell is Microsoft&#8217;s task automation and configuration management framework, consisting of a command-line shell and associated scripting language built on the .NET Framework. <a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Common-Intermediate-Language.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; float: right; padding-top: 0px; padding-left: 0px; margin: 0px 0px 0px 5px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"Common Intermediate Language\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Common-Intermediate-Language_thumb.png\" alt=\"Common Intermediate Language\" width=\"201\" height=\"240\" align=\"right\" border=\"0\" \/><\/a>PowerShell provides full access to COM and WMI, enabling administrators to perform administrative tasks on both local and remote Windows systems as well as WS-Management and CIM enabling management of remote Linux systems and network devices.\u201d\u00a0 &#8211; <\/em>Source: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Windows_PowerShell\" target=\"_blank\">Wikipedia<\/a><\/p>\n<p>While you\u2019d probably already knew PowerShell is built on the <a href=\"https:\/\/en.wikipedia.org\/wiki\/.NET\" target=\"_blank\">.NET Framework<\/a> and therefor compiles to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Common_Intermediate_Language\" target=\"_blank\">common intermediate language (CIL)<\/a> before being executed, just like all other .NET languages like Visual C++.NET, Visual C#.NET, VB.NET and more. As a result a PowerShell script that\u2019s executed effectively\u00a0 results in the same code as when it\u2019s executed in C# or C++, one of the strengths of .NET.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h1>Add-Type<\/h1>\n<p>In PowerShell, administrative tasks are generally performed by cmdlets (pronounced command-lets), which are specialized .NET classes implementing a particular operation. One of the more powerful cmdlets is <a href=\"https:\/\/technet.microsoft.com\/en-us\/library\/hh849914.aspx\" target=\"_blank\">Add-Type<\/a>.<\/p>\n<blockquote><p>Adds a Microsoft .NET Framework type (a class) to a Windows PowerShell session.<\/p><\/blockquote>\n<p>So with the Add-Type cmdlet you can basically run any .NET code as long as you can define it in a .NET Framework class. And yes this includes API\u2019s <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" style=\"border-style: none;\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/wlEmoticon-smile.png\" alt=\"Smile\" \/> . There are a number of parameters (all of which are optional) you can provide of which a few of them I\u2019ll describe below for all other information: <a href=\"https:\/\/technet.microsoft.com\/en-us\/library\/hh849914.aspx\" target=\"_blank\">MSDN<\/a><\/p>\n<p>For this article I\u2019ll assume you want to run or compile code from the PowerShell script, not refer to an assembly stored elsewhere (although that\u2019s possible). If you only want to run the code from the PowerShell script there\u2019s no need to specify the output, but if you want you can using <em>OutputType<\/em> and <em>OutputAssembly<\/em>.<\/p>\n<table border=\"1\" width=\"599\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"123\"><strong>Parameter<\/strong><\/td>\n<td valign=\"top\" width=\"251\"><strong>Description<\/strong><\/td>\n<td valign=\"top\" width=\"223\"><strong>Example values<\/strong><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"123\">Language<\/td>\n<td valign=\"top\" width=\"251\">Specifies the language that is used in the source code<\/td>\n<td valign=\"top\" width=\"223\">&#8211; CSharp (default)<br \/>\n&#8211; CSharpVersion3<br \/>\n&#8211; VisualBasic<br \/>\n&#8211; JScript<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"123\">CompilerParameters<\/td>\n<td valign=\"top\" width=\"251\">Specifies the options for the source code compiler. These options are sent to the compiler without revision.<\/td>\n<td valign=\"top\" width=\"223\">Options like \/unsafe, for more options see <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/2fdbz5xd.aspx\" target=\"_blank\">MSDN<\/a><\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"123\">OutputType<\/td>\n<td valign=\"top\" width=\"251\">Specifies the output type of the output assembly<\/td>\n<td valign=\"top\" width=\"223\">&#8211; Library<br \/>\n&#8211; ConsoleApplication<br \/>\n&#8211; WindowsApplication<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>By default no output type is specified (the code is not compiled to an assembly)OutputAssemblyGenerates a DLL (or EXE) file for the assembly with the specified name in the location. Enter a path (optional) and file name. Wildcard characters are permitted\u00a0TypeDefinition<\/p>\n<p>OR<\/p>\n<p>@Specifies the source code that contains the type definitions. Enter the source code in a string or here-string, or enter a variable that contains the source code.\u00a0UsingNamespaceSpecifies other namespaces that are required for the class. This is much like the Using keyword in C#.All .available .NET namespaces, for instance System.IO<\/p>\n<p>&nbsp;<\/p>\n<h1>Example<\/h1>\n<p>Knowing which cmdlet can be used to run or compile .NET code how is this actually done? Let me show how in two examples. The first example will show you how to run .NET code that enables you to directly use an API in PowerShell, in the second example I\u2019ll show you how to compile .NET code to a console application.<\/p>\n<p>&nbsp;<\/p>\n<h4>Example 1 \u2013 Run an API from a PowerShell script<\/h4>\n<p>In this example I\u2019ll show you how you can call the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms644950(v=vs.85).aspx\" target=\"_blank\">SendMessage<\/a> function (or API) directly from a PowerShell script. In the example I\u2019ve placed C# code in a string <span style=\"font-family: 'Courier New';\"><strong>$Win32_SendMessage<\/strong><\/span> which I\u2019ll add using the Add-Type cmdlet so I can call it from PowerShell.<\/p>\n<pre lang=\"powershell\">$Win32_SendMessage = @'\r\nusing System;\r\nusing System.Runtime.InteropServices;\r\n    public static class Win32 {\r\n    public static uint WM_CLOSE = 0x10;\r\n    public static uint WM_DESTROY = 0x0002;\r\n\r\n    [DllImport(\"user32.dll\", CharSet = CharSet.Auto, SetLastError = false)]\r\n    public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);\r\n}\r\n'@\r\n\r\nAdd-Type -TypeDefinition $Win32_SendMessage\r\n\r\n$p = @(Get-Process -Name Notepad)[0]\r\n[Win32]::SendMessage($p.MainWindowHandle, [Win32]::WM_CLOSE, $zero, $zero) &gt; $null<\/pre>\n<p><em>The script will close Notepad by sending a <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms632617(v=vs.85).aspx\" target=\"_blank\">WM_CLOSE<\/a> message to the process.<\/em><\/p>\n<p>&nbsp;<\/p>\n<h4>Example 2 \u2013 Compile c# code to a console application<\/h4>\n<p>In this example I\u2019ll show you how to compile c# sharp code to a console application using PowerShell. The example\u00a0 is the typical Hello World code from the a the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/aa288463(v=vs.71).aspx\" target=\"_blank\">C# Hello World Tutorial<\/a>.<\/p>\n<pre lang=\"powershell\">Add-Type -OutputType ConsoleApplication -OutputAssembly \"HelloWorld.exe\" @'\r\npublic class Hello1\r\n{\r\n   public static void Main()\r\n   {\r\n      System.Console.WriteLine(\"Hello, World!\");\r\n   }\r\n}\r\n'@<\/pre>\n<p><em>The output of the script is an console application called \u201cHelloWorld.exe\u201d which, when executed, prints \u201cHello, World!\u201d on the screen.<\/em><\/p>\n<p>&nbsp;<\/p>\n<h1>RES Workspace Manager (optional)<\/h1>\n<p>Now you know how you can use PowerShell to run and compile <em>all <\/em>.NET code using PowerShell without having an IDE (like Visual Studio) let me show you how you do this using <a href=\"https:\/\/www.ressoftware.com\/res-workspace-manager\u200e\" target=\"_blank\">RES Workspace Manager<\/a>. Depending on your needs you want to use RES Workspace Manager, or not.<\/p>\n<p>The advantage of using RES Workspace Manager to run .NET code is timing and security,. You decide at what <strong>event<\/strong> (like user logon, network state change or when an application is launched \u2013 very <strong>powerful<\/strong>!) the code is executed from a managed environment. There\u2019s no need to worry about if the script files are accessible or when someone\u2019s changed it, that\u2019s all available by default.<\/p>\n<h4><\/h4>\n<h4>Command<\/h4>\n<p>RES Workspace Manager can execute <a href=\"https:\/\/support.ressoftware.com\/WorkspaceManagerAdminGuide2014\/20096.htm\" target=\"_blank\">commands<\/a> to run applications tools or tools but can also run a script. When code is put in the <em>script tab<\/em> and %script% is used in the command line (or parameter) a temporary file with the provided extension is created on execution.<\/p>\n<p>If RES Workspace Manager needs to execute a PowerShell script the following command line can be provided:<\/p>\n<pre>powershell.exe %script%<\/pre>\n<p>Personally I prefer to specify the full path and included parameters to set the execution policy, but his is optional:<\/p>\n<pre>%Windir%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -ExecutionPolicy Bypass %Script%<\/pre>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Execute-Command-Properties.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"Execute Command - Properties\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Execute-Command-Properties_thumb.png\" alt=\"Execute Command - Properties\" width=\"254\" height=\"214\" border=\"0\" \/><\/a><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Execute-Command-Script.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"Execute Command - Script\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Execute-Command-Script_thumb.png\" alt=\"Execute Command - Script\" width=\"254\" height=\"212\" border=\"0\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Dynamic Privileges<\/h4>\n<p>Even better is the ability to execute a command (or a script) with administrative privileges even when the user hasn\u2019t. This means that a regular user can execute a very powerful PowerShell script (calling API\u2019s and stuff) with administrative privileges without granting this user with permissions it shouldn\u2019t have. <a href=\"https:\/\/support.ressoftware.com\/WorkspaceManagerAdminGuide2014\/21075.htm\" target=\"_blank\">Dynamic Privileges<\/a> are cool IMHO, especially since you can enable this feature on a specific action for an application or for the whole application.<\/p>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Execute-Command-Properties-Dynamic-Priviliges.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"Execute Command - Properties - Dynamic Priviliges\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2014\/04\/Execute-Command-Properties-Dynamic-Priviliges_thumb.png\" alt=\"Execute Command - Properties - Dynamic Priviliges\" width=\"254\" height=\"212\" border=\"0\" \/><\/a><\/p>\n<p>.<\/p>\n<p>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are occasions where you need a custom solution to fulfill a requirement which cannot be solved with existing applications or tools. This is usually where scripting comes into the picture, nowadays we tend to built most scripts using Microsoft PowerShell as it\u2019s a very powerful framework with a huge repository of cmdlets. Nonetheless there [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[152,291],"tags":[655,654,672,618],"class_list":["post-6824","post","type-post","status-publish","format-standard","hentry","category-powershell","category-workpace-manager","tag-cil","tag-dotnet","tag-powershell","tag-res-workspace-manager"],"_links":{"self":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/6824","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/comments?post=6824"}],"version-history":[{"count":5,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/6824\/revisions"}],"predecessor-version":[{"id":6838,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/6824\/revisions\/6838"}],"wp:attachment":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/media?parent=6824"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/categories?post=6824"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/tags?post=6824"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}