{"id":2483,"date":"2010-02-20T00:00:00","date_gmt":"2010-02-20T00:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudio\/2010\/02\/20\/msbuild-task-factories-guest-starring-windows-powershell\/"},"modified":"2019-04-03T22:59:45","modified_gmt":"2019-04-04T05:59:45","slug":"msbuild-task-factories-guest-starring-windows-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/visualstudio\/msbuild-task-factories-guest-starring-windows-powershell\/","title":{"rendered":"MSBuild Task Factories: guest starring Windows Powershell"},"content":{"rendered":"<p>One of the cool new features of MSBuild 4.0 is the extensible task factory.&#160; Task factories allow you to include scripts directly in your project file (or an imported .targets file) and have those scripts parsed and executed by your favorite interpreter.&#160; Those scripts might even be C# or VB.NET code snippets that get compiled into assemblies and executed on-the-fly during the build.&#160; This significantly lowers the bar to doing specialized work in your build for which there is no built-in MSBuild Task, since you don\u2019t have to check into your source control repository a precompiled .dll with your custom task any more.&#160; You may still want to do that for performance reasons or for the design-time experience of writing MSBuild tasks in C# and get all the C# Intellisense that you only get in a C# project, but for short tasks, \u201cinline tasks\u201d that are built and executed on-the-fly may be just the ticket you need.<\/p>\n<p>MSBuild 4.0 ships with C#, VB.NET and XAML task factories built-in, so you can define a custom task in C# or VB.NET inline today.&#160; But writing your own task factory will allow you to write inline tasks in Perl, Python, or in this case\u2026 Windows Powershell script.<\/p>\n<p>Consider, for the sake of example, that there is no MSBuild task that sends an email at the conclusion of a build.&#160; Fixing that with a custom MSBuild task, compiled into a .dll, seems a bit heavyweight.&#160; But defining that task right there in your project file is easy.&#160; Here\u2019s how you might write a Powershell inline task using the Windows Powershell task factory.&#160; Notice below how we first define the task in terms of the code it executes and its input and output parameters.&#160; Then in a standard MSBuild Target we invoke that inline task as we would any other MSBuild task.&#160; <\/p>\n<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\r\n&lt;Project ToolsVersion=&quot;4.0&quot; DefaultTargets=&quot;Build&quot; xmlns=&quot;http:\/\/schemas.microsoft.com\/developer\/msbuild\/2003&quot;&gt;\r\n  &lt;UsingTask\r\n    TaskFactory=&quot;WindowsPowershellTaskFactory&quot;\r\n    TaskName=&quot;SendMail&quot;\r\n    AssemblyFile=&quot;$(TaskFactoryPath)WindowsPowershellTaskFactory.dll&quot;&gt;\r\n    &lt;ParameterGroup&gt;\r\n      &lt;From Required=&quot;true&quot; ParameterType=&quot;System.String&quot; \/&gt;\r\n      &lt;Recipients Required=&quot;true&quot; ParameterType=&quot;System.String&quot; \/&gt;\r\n      &lt;Subject Required=&quot;true&quot; ParameterType=&quot;System.String&quot; \/&gt;\r\n      &lt;Body Required=&quot;true&quot; ParameterType=&quot;System.String&quot; \/&gt;\r\n      &lt;RecipientCount Output=&quot;true&quot; \/&gt;\r\n    &lt;\/ParameterGroup&gt;\r\n    &lt;Task&gt;\r\n      &lt;![CDATA[\r\n        $smtp = New-Object System.Net.Mail.SmtpClient\r\n        $smtp.Host = &quot;mail.microsoft.com&quot;\r\n        $smtp.Credentials = [System.Net.CredentialCache]::DefaultCredentials\r\n        $smtp.Send($From, $Recipients, $Subject, $Body)\r\n        $RecipientCount = $Recipients.Split(';').Length\r\n        $log.LogMessage([Microsoft.Build.Framework.MessageImportance]&quot;High&quot;, &quot;Send mail to {0} recipients.&quot;, $recipientCount)\r\n      ]]&gt;\r\n    &lt;\/Task&gt;\r\n  &lt;\/UsingTask&gt;\r\n  &lt;PropertyGroup&gt;\r\n    &lt;BuildLabEmail&gt;buildlab@yourcompany.com&lt;\/BuildLabEmail&gt;\r\n    &lt;BuildRecipients&gt;interested@party.com;boss@guy.com&lt;\/BuildRecipients&gt;\r\n  &lt;\/PropertyGroup&gt;\r\n  &lt;Target Name=&quot;Build&quot;&gt;\r\n    &lt;SendMail From=&quot;$(BuildLabEmail)&quot; Recipients=&quot;$(BuildRecipients)&quot; Subject=&quot;Build status&quot; Body=&quot;Build completed&quot;&gt;\r\n      &lt;Output TaskParameter=&quot;RecipientCount&quot; PropertyName=&quot;RecipientCount&quot; \/&gt;\r\n    &lt;\/Add&gt;\r\n  &lt;\/Target&gt;\r\n&lt;\/Project&gt;<\/pre>\n<p>This project would build, and send a built completion email to recipients determined by the project itself.&#160; The only assembly you need is the Windows Powershell task factory itself, which can be reused for all your projects that include inline Windows Powershell scripts.<\/p>\n<p>Note that the inline task above will not run without the task factory .dll that it points to, which in this case is <em>not<\/em> shipped with VS2010.&#160; The <a href=\"http:\/\/code.msdn.microsoft.com\/PowershellFactory\">Windows Powershell task factory is available<\/a> as a sample task factory on the MSDN Code Gallery.&#160; Feel free to check it out, and give feedback.&#160; It\u2019s just a sample, so all the \u201cno guarantees for fitness to any particular task\u201d limitations apply.&#160; But you get the source code, so you can tweak it or file bugs if you wish.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the cool new features of MSBuild 4.0 is the extensible task factory.&#160; Task factories allow you to include scripts directly in your project file (or an imported .targets file) and have those scripts parsed and executed by your favorite interpreter.&#160; Those scripts might even be C# or VB.NET code snippets that get compiled [&hellip;]<\/p>\n","protected":false},"author":2685,"featured_media":255385,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[155],"tags":[5,37,172,133],"class_list":["post-2483","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-studio","tag-csharp","tag-msbuild","tag-python","tag-xaml"],"acf":[],"blog_post_summary":"<p>One of the cool new features of MSBuild 4.0 is the extensible task factory.&#160; Task factories allow you to include scripts directly in your project file (or an imported .targets file) and have those scripts parsed and executed by your favorite interpreter.&#160; Those scripts might even be C# or VB.NET code snippets that get compiled [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2483","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/users\/2685"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/comments?post=2483"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/posts\/2483\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media\/255385"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/media?parent=2483"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/categories?post=2483"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/visualstudio\/wp-json\/wp\/v2\/tags?post=2483"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}