Automating the world one-liner at a time…
Windows PowerShell CTP3 has a lot of very cool things. CTP2 introduced the Add-Type cmdlet, which allowed you to dynamically compile C# in PowerShell. It was actually possible to use the CompilerParameters to Add-Type to make a console application, but it wasn't particularly easy. In CTP3, we've made this a lot easier to do.
There's now an -OutputType parameter for Add-Type. It can either output a Library (the default), a ConsoleApplication, or a WindowsApplication. Check out this really quick "Hello World" program built using Add-Type.
Add-Type -OutputType ConsoleApplication -OutputAssembly HelloWorld.exe @" using System; public class MyProgram { public static void Main(string[] args) { Console.WriteLine("Hello World"); } } "@
Hope this Helps,
James Brundage [MSFT]
Very Cool .... I was trying to think when would you want to do this ?
There's no value in marking the class and the Main() method 'public'.
PowerShell Team is trying to make admins learn C#.
How fearful this plan is!
@Smith
> PowerShell Team is trying to make admins learn C#.
Absolutely not!
Now we do want to make it super easy to learn C# for those Admins that want to (some will) but we have zero interest in forcing admins to learn C#.
We provide functions like these so that DEVELOPERS (or advanced scripters) can use PowerShell to provide the right abstractions to Admins.
Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
@Jeffrey
It's just a joke, of course:)
I very quickly run into this little gem of an error....
I'm running v2.0 ctp3 just downloaded!
just copied the string and pasted it to ps...
What did I do wrong!
Unrecognized token in source text.
At line:1 char:72
+ Add-Type -OutputType ConsoleApplication -OutputAssembly HelloWorld.exe <<<< @"
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnrecognizedToken
@ lcr
You did nothing wrong, because the text is not preformatted, here documents @"
"@
End up with an extra non-standard space at the end of the first line, which will often break it (it's a strange copy/paste behavior from Internet Explorer)
Simply delete the last character on the line.
@chris
I think the case of writing a WindowsApplication is more interesting that the case of ConsoleApplication, but one reason you might want to do this is to expose the information in a way that's easier for a command script, VBScript, or JScript to handle.
It's also valuable if systems administrators want to use the power of PowerShell to make a task easier, but want to protect their individual scripts a little more.
James Brundage posted a blog entry How To Write a Console Application in PowerShell with Add-Type which
What is a use case for this?
Why would this help an admin to protect their scripts? I could do the same by writing the code in .cs file and running csc.exe.
The assumption seems to be that admins WANT to write C# (or VB.NET for that matter). Is that what you are aiming for?
@Alexander
Speeding up parts of a script would be a use for this, check the 'burn-console' and 'invoke-inline' scripts at: http://www.leeholmes.com/blog/default,month,2005-12.aspx
Performance benefits are one case, but in that case it would be better to compile C# and use it in PowerShell.
Making a console application is a simplified example of the more interesting example, packing a script into any application this way.
Your company (Sapien) makes a gui builder. You could use this technique to pack what gets created with your gui builder so that the final customer is unaware of its scripted origins.
We are doing that, but I don't see how being able to compile C# from within PowerShell does anything for that. You can't compile PowerShell into an assembly. Or am I missing something?
I'm trying to use this with a C# snippet that parses an XML (I know I can do it directly Powershell, but I want to test this out). I'm using CTP3. The problem is that when I try to add-type the snippet it doesn't find the System.Xml namespace. I've tried "-UsingNamespace" with no luck. So, neither of the following works:
Add-Type -TypeDefinition "using System.Xml;"
Add-Type -TypeDefinition "using System.Xml;" -UsingNamespace "System.Xml"
Obviously, the class that I'm using is bigger than that but it triggers the same problems. Why wouldn't this work?
Thanks
@ alex:
You can compile PowerShell into an assembly (that's why the parameter is -outputAssembly), as well as a console application, as well as a windows application
@ stephen
You don't have the Xml assembly referenced.
I normally use this trick to reference types I've already got:
Add-Type '
Code
' -ReferencedAssemblies ([XML].Assembly)
Each type has an assembly property, and it's easier to use a type you to get the assembly than it is to remember the full assembly names (at lesat for me)
Hope this helps,
hi,it seems my powershell doesn't support Add-Type cmdlet, when i run the scripts, the shell return some error info, which means can't recognize Add-Type as cmdlet.
Can somebody tell me why this pheno happens?