Automation–PowerShell Workflow Script Spotlight–Deploying Virtual Machine Manager Service Templates-More Examples!

Automation–PowerShell Workflow Script Spotlight–Deploying Virtual Machine Manager Service Templates-More Examples!

  • Comments 6
  • Likes

Hello,

So I was  having an #8minutediscussionwithCharlesJoy recently, and we thought it could be a good idea to build upon his recent blog post on scripting Service Templates, to provide another set of examples.

Charles covered how you could create a tenant with VMM through PowerShell, and create/deploy objects on behalf of this tenant, leveraging the -ForOnBehalfOf and –OnBehalfOf switches in VMM cmdlets.

In today’s post, we’ll look at a PowerShell script showcasing how 3 very simple and specific actions can be achieved in a generic way (not using the –OnBehalfOf syntax):

  1. Deploy a Service Template
  2. Scale out a Service Template
  3. Assigning an encrypted Global Setting in a Service Template (in addition to a few standard non-encrypted Global Settings, just like Charles had in his post)

These examples could be used in any context : PowerShell, Service Management Automation (SMA), Orchestrator. While the syntaxes below will be extracts from SMA, I’ll actually finish the post by explaining how you could modify the scripts to have them run in Orchestrator as well.

 

The sample script

This single PowerShell workflow shows all the different items I’d like to show in this post:

  • It checks if a specific service name already exists (lines 17-24)
  • If it does not exist, the service is created, ans assigns the different global settings, including an encrypted setting (lines 41-58 – see the notes below, as this part of the script could be much shorter if there was no global settings and if the VM was not explicitely given a name)
  • If it exists already, the service is scaled out (lines 63-69)
  • The name of the new VM was actually computed before in the script (lines 28-35)
  • finally, the script outputs the name of the VM that was created (line 73)

In the sample below, the script actually deploys the template from the Oracle Self-Service Kit. The encrypted global setting “OracleUserPass” is used during VM deployment to install Oracle Database 12c with a specific Oracle Home User account (see the notes for more information).

 

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077

workflow DeployScaleOut-VMMTemplate
{
   
    param (
        [parameter(Mandatory=$true)]
        [string]$ServiceName
    )
   
    $VMMServer = Get-AutomationVariable -Name 'Blog-STSample-VMMServerName'
    $VMMCreds = Get-AutomationPSCredential -Name 'Blog-STSample-VMMCreds'
    $VMPrefix = "ORCL-DEMO"
    $DomainNameFQDN = "CONTOSO.COM"
    $VMMCloud = "Cloud for Contoso BU"
    $VMMServiceTemplate = "Oracle Farm"
   
    #First, we check if the service already exists in VMM
    $ServiceExists = InlineScript { 
         $ServiceExists = $false      
        import-module virtualmachinemanager
        $result = Get-SCVMMServer -ComputerName $Using:VMMServer
        $Svc = Get-SCService -Name $Using:ServiceName
        If ($Svc) {$ServiceExists = $true}
        $ServiceExists       
    }-PSComputerName $VMMServer -PSCredential $VMMCreds
   
    # Then we determine the name of the VM we need to create, using the chosen naming pattern
    # This is mandatory for scale out, not for creation (see the blog notes)
    $NbVM = InlineScript {       
        import-module virtualmachinemanager
        $result = Get-SCVMMServer -ComputerName $Using:VMMServer
        $NbVM = (Get-VM | where-object {$_.Name -match $Using:VMPrefix}).Count
        $NbVM = $NbVM+1
        $NbVM       
    }-PSComputerName $VMMServer -PSCredential $VMMCreds
    $NewVMName = $VMPrefix + "-" + $NbVM + "." + $DomainNameFQDN
       
    If ($ServiceExists -eq $false)
   
    {
       #Create a new service
       InlineScript{
                import-module virtualmachinemanager
                $result = Get-SCVMMServer -ComputerName $Using:VMMServer
                $Cloud = Get-SCCloud -Name $Using:VMMCloud
                $ST=Get-SCServiceTemplate -Name $Using:VMMServiceTemplate
                $ServiceConfig = New-SCServiceConfiguration -ServiceTemplate $ST -Name $Using:ServiceName -Cloud $Cloud
                Get-SCServiceSetting -ServiceConfiguration $ServiceConfig -Name "AdminPort" | Set-SCServiceSetting -Value "5501"
                Get-SCServiceSetting -ServiceConfiguration $ServiceConfig -Name "DBPort" | Set-SCServiceSetting -Value "1521"
                Get-SCServiceSetting -ServiceConfiguration $ServiceConfig -Name "LocalFolder" | Set-SCServiceSetting -Value "C:\Or12c"
                Get-SCServiceSetting -ServiceConfiguration $ServiceConfig -Name "OracleDBMedia" | Set-SCServiceSetting -Value "\\fileserver1\sources\Oracle\Database\12cR1\database"
                Get-SCServiceSetting -ServiceConfiguration $ServiceConfig -Name "OracleUserAcct" | Set-SCServiceSetting -Value "oracleuser"
                $SecurePass = "YouDidNotSeeAnything!01" | ConvertTo-SecureString -AsPlainText -Force
                Get-SCServiceSetting -ServiceConfiguration $ServiceConfig -Name "OracleUserPass" | Set-SCServiceSetting -SecureValue $SecurePass
                $CT = Get-SCComputerTierConfiguration -ServiceConfiguration $ServiceConfig
                $VMConfig = Get=SCVMConfiguration -ComputerTierConfiguration $CT
                Set-SCVMConfiguration -VMConfiguration $VMConfig -Name $Using:NewVMName -ComputerName $Using:NewVMName
                $NewService = New-SCService -ServiceConfiguration $ServiceConfig
            } -PSComputerName $VMMServer -PSCredential $VMMCreds          
    }
    Else
    {
        #Scale out the existing service
        InlineScript{
            import-module virtualmachinemanager
            $result = Get-SCVMMServer -ComputerName $Using:VMMServer
            $Svc = Get-SCService -Name $Using:ServiceName
            $CT = Get-SCComputerTier -Service $Svc
            $result = New-SCVirtualMachine -ComputerTier $CT -Name $Using:NewVMName -ComputerName $Using:NewVMName
        } -PSComputerName $VMMServer -PSCredential $VMMCreds

    }
    # We return the name of the VM that was created
    Return $NewVMName  
   

}

 

Notes :

  • The script does similar items multiple times through InlineScript – while it could be optimized, there are some benefits in doing so : you could have PowerShell checkpoint for easy retart. Plus the current formatting makes it easy to port this to an Orchestrator Runbook if needed (see the next paragraph in this blog post)
  • Both when creating and scaling out the service, the script explicitly assigns a name and computer name to the VM. While the VM name is mandatory when scaling out, no VM name or computer name is actually needed when creating the service, if you use a patterm in your service template in VMM. Here, I assign a name in both situations, to be consistent. Assigning the VM name and computer name when creating the service is at lines 54 to 56.
  • As a best practices, I try to use as many SMA variables (or Orchestrator variables) as possible, and some of the PowerShell variables in this could be SMA variables as well. I just wanted to show you this is not mandatory, and you can mix and match as needed.
  • The password is in clear text here. This is obvisouly not a best practice, and this is just to be explicit about what is being done. But in the real world you would likely have it as an encrypted SMA or Orchestrator variable. The nice thing about this is that both Orchestrator and SMA just let you treat encrypted variables just like standard variables. For example with SMA, you would just call the encrypted variable using the Get-AutomationVariable cmdlet, as in line 9.
  • This scale out example is for a single-tier service template. If your service template has multiple tiers, you would have to filter to pick the right tier with the Get-SCComputerTier cmdlet, using a Where clause

 

Wait, what if I am using Orchestrator? Can I still use this script?

Of course! The previous script can easily be used in Orchestrator as well. While it could certainly be optimized with less remoting when running for SMA, the scructure of the previous sample actually lends itself well for multiple “Run .NET Script” activities within PowerShell, one for each InlineScript paragraph, with published data when values need to flow between activities.

For example, getting the new VM information would look like this, also using Orchestrator variables instead of SMA variables:

image_thumb7

image_thumb8

And scaling out would look like this, using a mix of variables and the published data:

image_thumb11

When it comes to the script itself, you may notice that the only change is that, instead of using a InlineScript call, you would be using Invoke-Command. Simple and easy!

Note : The Orchestrator example does things a bit differently than the SMA example : The first part of the Orchestrator sample is getting the new VM number and the new VM name is computed in the second activity, whereas in the SMA example the full name is directly computed in the first part. But you get the idea Smile

 

I hope you enjoyed this quick post and will find its content valuable. Be sure to check our blog for more Windows Server and System Center adventures!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • #First, we check if the service already exists in VMM

       $ServiceExists = InlineScript {

            $ServiceExists = $false      

           import-module virtualmachinemanager

           $result = Get-SCVMMServer -ComputerName $Using:VMMServer

           $Svc = Get-SCService -Name $Using:ServiceName

           If ($Svc) {$ServiceExists = $true}

           $ServiceExists        

       }-PSComputerName $VMMServer -PSCredential $VMMCreds

    That InlineScript block has few unnecessary lines of code:

    #First, we check if the service already exists in VMM

       $ServiceExists = InlineScript {

           import-module virtualmachinemanager

           Get-SCVMMServer -ComputerName $Using:VMMServer | Out-Null

           $Svc = Get-SCService -Name $Using:ServiceName

           If ($Svc) {$true} else {$false}  

       }-PSComputerName $VMMServer -PSCredential $VMMCreds

  • Hello Aleksandar,

    You are right that the script could be optimized just like you mentioned.

    Thanks for sharing this!

  • Teachers open the door, but you must enter by yourself.

  • if we have a two-tier service then how will we identify in which tier we want to add a new vm.

  • Hi Pankaj

    You can choose the tier to scale out at the line with the cmdlet Get-SCComputerTierConfiguration (line 54 in the sample script in the blog post). In the example, it does not filter anything since there was only a single tier in the template used, but you could add a "where" clause. For example : | Where Name -eq "YourTierName"

    Thanks!