ScorpioTek Solutions
07-filler-left Information about ScorpioTek Services Offered by ScorpioTek Training Courses Offered by ScorpioTek Technology Blog by ScorpioTek Contact us for more information on training/services 08-filler-right
06-message

Archive for the ‘SCVMM’ Category

How to correctly invoke a PowerShell Function that has the same name in two Libraries

Monday, February 18th, 2013

I am currently authoring a PowerShell reporting script that exclusively uses functions from the Windows Server 2012 Hyper-V API.  When I imported the module for System Center Virtual Machine Manager, I noticed that a function that I previously used was giving me an error:

Get-SCVMHost : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'ComputerName'. Specified method is not supported.

Get-SCVMHost : Cannot convert ‘System.Object[]‘ to the type ‘System.String’ required by parameter ‘ComputerName’. Specified method is
not supported.

I then realized that the Get-VMHost commandlet was now being invoked from the SCVMM library, which does not support getting hosts from an array of names like the Hyper-V API does.  So how does how go about letting PowerShell know that we want to use the Get-VMHost commandlet from Hyper-V?

I had no idea, and searching the web yielded nothing.  I then followed my Visual Studio instinct and thought intelisense would shed some light…and it did.

When I right-clicked and selected Start Intellisense on the function, I could see which library it was using:

The Get-Host from SCVMM is the one being used

The Get-Host from SCVMM is the one being used

I scrolled down a bit more and found the one I wanted:

Hyper-V API Function

Hyper-V API Function

Once I selected the correct fucntion, PowerShell ISE took care of the rest and wrote down the syntax (which I had no idea about) to avoid ambiguity when calling functions:

pac0915 2013-02-18 10-03-59

How to Cut SCVMM Deployments to 1/2 of the Time

Tuesday, August 2nd, 2011

When dealing with SCVMM deployments, you may be aware that copies of VMs (clones, templates, etc.) are done via BITS using https. This means that any traffic from source through destination is encrypted, which might not be the desired functionality if you don’t need encryption.

Point in case: we are currently cloning 100 VMs (~40 GB each one) in a cluster. The time per VM to be cloned was about 40 minutes, which was too much. After some surfing, I came across the ‘AllowUnencryptedTransfers’ switch.  This is used with the Set-VMHostGroup comandlet to remove the encryption of the transfers.  This basically translates to “copies are going to be a lot faster!”

To activate this in your SCVMM hosts, all you need is this command:

Set-VMHostGroup -VMHostGroup “All Hosts” -AllowUnencryptedTransfers $true

You can then verify that the change took place by looking at the Get-VMHostGroup command and looking at this row:

After you set that, look at the jobs in your SCVMM console and enjoy the speed!  (in our tests the VM was cloned in 14 minutes vs. 30 minutes using https)

Booyah!

PowerShell Script to Automatically Update Integration Services on SCVMM

Monday, March 7th, 2011

We just upgraded all hosts to Windows Server 2008 R2 SP1 – and the performance of our VMs was really bad. It turns out that if you upgrade the Integration Services on the VMs, then everything behaves the way it should be. Here is the script we used for updating integration services on all machines that were running on our SCVMM server:

Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager

$VMM = Get-VMMServer “SCVMM4″ #Set this to the name of your SCVMM server

$VMs = Get-Vm #Get all the VMs on the SCVMM Server

foreach ($VM in $VMs) {

if ($VM.Status -eq ‘Running’) { #Only Work with those Vms that are Off

Write-Host ‘Starting with ‘$VM.Name

Shutdown-VM $VM #Machine needs to be off for this to work

Set-VM –VM $VM –InstallVirtualizationGuestServices $TRUE

Start-VM $VM

}

}


SCVMM Extender Group Deployment Feature

Friday, May 14th, 2010

During the last few months we’ve been playing around with System Center Virtual Machine Manager (SCVMM) to deploy virtual machines for various lab configurations.  SCVMM is an interesting product. and while it lacks in some features, it gives you the ability of create anything you’d want it to be by exposing a PowerShell API.  By using this PowerShell API, we’ve been able to extend SCVMM for our particular needs and we’ve built the SCVMM Extender.  As of now, it is in very early stages, but it allows us to carry out “Group Deployment”, which is a real time saver in some lab scenarios.

For more info on this feature, check out the video below:

Adding Multiple Virtual Networks to Multiple Hosts in a Snap

Thursday, May 6th, 2010

Today I received a request to deploy 120 virtual machines in SCVMM, however these machines needed to be deployed in groups of 4 across in each host.  The real problem with this scenario was that none of the hosts had the virtual networks I required.  These VMs are part of  a Windows HPC Server demo and they required a combination of a public network, one internal network, and 2 private networks.  If you import into Hyper-V a VM export that does not have the exact name as the virtual network specified in the export, it will not be connected.  So if you deploy 1,000 machines and their networks are not set right, then you have to configure them manually…yeah…good luck.

What I did to solve this problem was to download the PowerShell Management Library and write the following lines of code:

Import-Module 'C:\Program Files\modules\HyperV'

$hostName = 'Pac07010'

New-VMPrivateSwitch "Application" -server $hostName

New-VMPrivateSwitch "Private" -server $hostName

New-VMINternalSwitch "Enterprise" -server $hostName

And that’s it.  I was lucky enough that my machines were named in consecutive order, so I just wrote a for loop to iterate through the machine collection.  I then sat back with a big smile on my face.  I have really not faced a problem that the PowerShell Management Library has not been able to tackle – thank YOU jamesone!



How to Execute Remote PowerShell Commands using C#

Sunday, April 11th, 2010

UPDATE: The post below works when you are trying to execute simple commands.  I had issues when trying to execute full scripts.  After searching some more, I found amazing tutorials on how to carry out this procedure, check them out:


Before I start this post that I am urging to write (before I forget all I did), I must clarify that all the code here was from various sites/forums.  All I did was to try and get the combination right, which basically took all of my time yesterday.  Nonetheless, at least it’s working.

So what I am writing at this moment is a C# application that will issue SCVMM commands from any machine in my domain.  SCVMM’s API is 100% PowerShell, so anything you need to run automatically via code in SCVMM, needs to be called through PowerShell somehow.

PowerShell v2.0 includes Remoting, which allows you to issue PowerShell commands remotely on other machines by using Windows Remote Management (WinRM).  So let’s see how on Earth this is done:

Pre-reqs

Before you do any of this, you must run the following command in an admin PowerShell command prompt on the machine where you would like to run the remote command:

winrm quickconfig

The Code References

You need to use the correct version of System.Management.Automation.dll.  If you are running Windows 7 / Windows Server 2008 R2, you must include this reference in your project from the following path:

C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll

Note: When importing the aforementioned DLL, I was having all kinds of issues with Visual Studio 2008.  I tried it with Visual Studio 2010 and it worked right away.

The Namespaces

Include the following namespaces in your code:

using System.Management.Automation; // Windows PowerShell namespace
using System.Management.Automation.Runspaces; // Windows PowerShell namespace
using System.Security; // For the secure password

The Function

This is the function you need to invoke when you want to run a remote command.  The incoming string, scriptText, is the PowerShell command you would like to execute:

public static string RunScript(string scriptText)
        {

           Runspace remoteRunspace = null;
           openRunspace("http://SERVERNAME:5985/wsman",
                "http://schemas.microsoft.com/powershell/Microsoft.PowerShell",
                @"DOMAIN\USERNAME",
                "PASSWORD",
                ref remoteRunspace);

                StringBuilder stringBuilder = new StringBuilder();
                using (PowerShell powershell = PowerShell.Create())
                {
                    powershell.Runspace = remoteRunspace;
                    powershell.AddCommand("get-process");
                    powershell.Invoke();
                    Collection<PSObject> results = powershell.Invoke();
                    remoteRunspace.Close();
                    foreach (PSObject obj in results)
                    {
                        stringBuilder.AppendLine(obj.ToString());
                    }
                }

                return stringBuilder.ToString();
         }

Note that you must replace DOMAIN\USERNAME with your domain and username.  You must also replace PASSWORD with your password.  I really don’t know how to carry this out using my logged-in credentials, so until then, I’ll have to include my password in the code, which is crappy but works.  Also note that you must also replace SERVERNAME with the machine you are trying to connect to.  The port MUST be 5985, if you try the default (80), it will fail to connect (at least, it did in my case).

The magic happens inside the static function openRunspace which is defined as follows:

        public static void  openRunspace(string uri, string schema, string username, string livePass, ref Runspace remoteRunspace)
        {
            System.Security.SecureString password = new System.Security.SecureString();
            foreach (char c in livePass.ToCharArray())
            {
                password.AppendChar(c);
            }
            PSCredential psc = new PSCredential(username, password);
            WSManConnectionInfo rri = new WSManConnectionInfo(new Uri(uri), schema, psc);
            rri.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
            rri.ProxyAuthentication = AuthenticationMechanism.Negotiate;
            remoteRunspace = RunspaceFactory.CreateRunspace(rri);
            remoteRunspace.Open();
        }

Let me know if it works for you in the comments.

Sources:

How to Invoke SCVMM PowerShell Commands

Thursday, February 18th, 2010

When you install SCVMM, you get a link a to run any SCVMM commands you want:

That is great for running quick commands on the PS command prompt – but what if you want to run SCVMM commands from the PowerShell’s ISE?

This is the only command you need, add it to your profile so you don’t have to type them every time:

Add-PSSnapin Microsoft.SystemCenter.VirtualMachineManager

If you want to find the commands that are available, use this:

Get-Command -PSSnapin Microsoft.SystemCenter.VirtualMachineManager | sort Name

This is more a reminder to myself than anything else, but if it can help anyone else, then great! :)