<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'PowerShell', 'hyper-v', 'VBScript', and 'automation'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=PowerShell,hyper-v,VBScript,automation&amp;orTags=0</link><description>Search results matching tags 'PowerShell', 'hyper-v', 'VBScript', and 'automation'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>[OT] : Windows Activation, en masse</title><link>http://sqlblog.com/blogs/aaron_bertrand/archive/2011/03/13/ot-windows-activation-en-masse.aspx</link><pubDate>Sun, 13 Mar 2011 20:07:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:34104</guid><dc:creator>AaronBertrand</dc:creator><description>&lt;p&gt;This weekend I discovered a minor issue in one of my virtual environments. I had built out 100 VMs based on a Hyper-V template, but I forgot to activate the original source before creating the template, so all of the machines were suddenly out of compliance. While easy enough on a one- or two-machine basis to just log into the machine and activate manually, there was no way I was even going to dream of repeating that process on 100 machines.&lt;/p&gt;

&lt;p&gt;&lt;font size="4"&gt;&lt;br&gt;My First Reaction : PowerShell&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Whenever I do anything with this number of machines, I assume there's an easy way to do it in PowerShell. My searching throughout the 'toobz led to many promising scripts; unfortunately, most dealt with the old WMI class used prior to Windows 7 and Windows Server 2008 R2: &lt;a href="http://msdn.microsoft.com/en-us/library/aa394520%28VS.85%29.aspx" title="http://msdn.microsoft.com/en-us/library/aa394520%28VS.85%29.aspx" target="_blank"&gt;Win32_WindowsProductActivation&lt;/a&gt;. In the latest versions of the operating system, trying to utilize this class leads to generic "Invalid Class" errors; the methods and properties associated with this class have been split out into two new classes: &lt;a href="http://msdn.microsoft.com/en-us/library/cc534596%28VS.85%29.aspx" title="http://msdn.microsoft.com/en-us/library/cc534596%28VS.85%29.aspx" target="_blank"&gt;SoftwareLicensingProduct&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/cc534597%28VS.85%29.aspx" title="http://msdn.microsoft.com/en-us/library/cc534597%28VS.85%29.aspx" target="_blank"&gt;SoftwareLicensingService&lt;/a&gt; (did I mention I'm really glad they're moving away from the Win32_ prefix?).&amp;nbsp; The only PowerShell script I found that dealt with these new classes was &lt;a href="http://blogs.technet.com/b/jamesone/archive/2009/07/22/how-to-activate-windows-from-a-script-even-remotely.aspx" title="http://blogs.technet.com/b/jamesone/archive/2009/07/22/how-to-activate-windows-from-a-script-even-remotely.aspx" target="_blank"&gt;a function created by James O'Neill&lt;/a&gt;; sadly, I could not get his version to work. I spent about an hour trying to tweak the script to make it work, but couldn't get past various errors. By default, the error I received was as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div style="padding:10px 20px;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;color:red;"&gt;Register-Computer : Cannot process argument transformation on parameter 'Productkey'. Cannot convert value to type System.String.&lt;br&gt;At line:30 char:18&lt;br&gt;+ Register-Computer &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;nbsp; "&amp;lt;product key&amp;gt;","&amp;lt;computer&amp;gt;"&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + CategoryInfo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : InvalidData: (:) [Register-Computer], ParameterBindin...mationException&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + FullyQualifiedErrorId : ParameterArgumentTransformationError,Register-Computer&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
 


&lt;p&gt;Not sure if this is an issue with the RegEx, but after removing the validation on the parameter and subsequently going through various other iterations, seeing many different error messages come out of the script, I gave up. A man only has so much patience, especially on the weekend.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;font size="4"&gt;Going Back to Basic(s) &lt;/font&gt;&lt;/p&gt;

&lt;p&gt;I don't want to say anything bad about PowerShell at this point, except that it's not the only tool in the toolbox, and it's not the magical cure for all that ails you. One thing I knew I would have little trouble getting to work would be VBScript. Assuming that I have 100 machines named VM-001, VM-002, ... , VM-099, VM-100, I could use the following script to activate them all in one swoop (sorry it's not color-coded, but it is fairly short):&lt;/p&gt;

&lt;blockquote&gt;
&lt;table bgcolor="#eeeeee" cellpadding="0" cellspacing="0"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style="padding:10px 20px;font-size:12px;font-family:consolas,lucida console,courier new,courier;-moz-background-inline-policy:continuous;"&gt;For i = 1 to 100&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; srv = "VM-" &amp;amp; right("000" &amp;amp; i, 3)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; wmi = "winmgmts:{impersonationLevel=impersonate}!\\" &amp;amp; srv &amp;amp; "\root\cimv2"&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each o in GetObject(wmi).InstancesOf("SoftwareLicensingProduct")&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If&amp;nbsp; o.ProductKeyID &amp;amp; "" &amp;gt; "" Then o.Activate()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each o in GetObject(wmi).InstancesOf("SoftwareLicensingService")&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; o.RefreshLicenseStatus()&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next &lt;br&gt;&lt;br&gt;Next&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/blockquote&gt;


&lt;p&gt;Now, I don't handle all of the little nuances that James was concerned about, but it certainly did the job, and allowed me to move on with my Sunday. Once I had the script nicely formatted, it took about 6 minutes to run against all 100 servers, and random spot checks on VM-034, VM-066 and VM-092 proved that the machines had all been activated.&lt;/p&gt;&lt;p&gt;Note that without the RefreshLicenseStatus() call, when you log into any machine (at least within a certain amount of time), you'll get a prompt about verifying that Windows is genuine. When you proceed, it will simply tell you that Windows has been successfully activated. I also realize that your list of servers might not be so conveniently-named; you can just as easily pull the list of servers from a text file or database.&lt;br&gt;&lt;/p&gt;&lt;p&gt;Hopefully this will come in handy for someone as forgetful as me.&lt;/p&gt;&lt;p&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;</description></item></channel></rss>