vRA/vRO 8.1 Powershell – Peaking Under The Hood

One of the new features in vRealize Automation (vRA) and vRealize Orchestrator (vRO) 8.1 was support for PowerShell. This means there are now 4 scripting language options for Action Based Extensibility (ABX) in vRA and Workflows in vRO. In this post, I’m going to have a look at some of the technical details of the PowerShell implementation.

Why We Should Care

There’s two items that come to mind about why we should care about the PowerShell implementation. The first relates to the history of PowerShell itself. Up until 2016, PowerShell had been based upon the full .NET framework. In that year, Microsoft announced PowerShell Core, which was based on .NET Core. This allowed PowerShell to be used on non-Windows platforms like Linux. This new “branch” of PowerShell had reduced functionality, with many modules no longer working. Eventually PowerShell Core was re-branded to a 6.x version line. In March 2020, PowerShell 7 was released. This version was an attempt to close the gap in functionality between the two branches.

The second item is how PowerShell was used in vRA/vRO 7.x. In 7.x it was possible to add a PowerShell host. The PowerShell host was a Windows system configured to allow vRO to remote into it to execute commands. This created an incredible amount of flexibility because you could install any modules you liked on the host. On the down side, it added complexity (more moving parts to manage) and security issues (like ensuring the PowerShell Host had a network path to each target, and Kerberos double-hopping issues).

With this background in mind, it becomes relevant to figure out what implementation of PowerShell is used in vRA/vRO and other information about the implementation.

Read morevRA/vRO 8.1 Powershell – Peaking Under The Hood

Bulk Add Flavor Mappings Using vRA 8 REST API

One of the features added in vRealize Automation 8 (vRA 8) was Flavor Mappings. Flavor Mappings allow various instance types on different cloud providers to be associated with a platform-agnostic label. While it was possible to do something similar in vRA 7, it required a lot of scripting to handle the logic of the choice made. Like many of VMware’s newer products, vRA 8 has a REST API for executing most tasks, and this includes management of Flavor Mappings. Because adding these in bulk can be tedious, I looked at how it might be done with a bit of automation.

Workflow Overview

The vRealize Automation 8.1 API Programming Guide is a good starting point for looking at automating tasks in vRA 8. It has the steps relating to getting authentication done, as well as some general administrative tasks. In the case of what I was trying to achieve, the general workflow looks like this:

Flavor Mapping Workflow
Flavor Mapping Workflow

Read moreBulk Add Flavor Mappings Using vRA 8 REST API

PowerShell 7.0 – Cmdlet Compatibility

In my first post about PowerShell 7.0, I made mention of a major issue that most likely prevent adoption of PowerShell 6.x by Windows system administrators. This issue was the loss of functionality in 6.x, specifically that some cmdlets would not be available due to 6.x being built on .NET Core. The release of 7.0 is meant to help address this, which is the intent of this post.

Cmdlet Compatibility Approach

In reviewing the compatibility for 5.1 and 7.0, I used the management server in my home lab. This is a Windows Server 2019 virtual machine, so it shares the common set of cmdlets that Windows 10 has. As a management server, it also has some additional modules/cmdlets available:

  • Windows Server Role-based modules such as ActiveDirectory and DnsServer
  • SQLPS from the installation of SQL Server 2014
  • cmdlets associated with VMware’s PowerCLI
  • cmdlets associated with ChefDK
  • AWS’s PowerShell module

While not comprehensive, this does give good coverage of built-in, Microsoft-provided and third-party provided items.

Read morePowerShell 7.0 – Cmdlet Compatibility

PowerShell 7.0 – Introduction, History, Installation

Microsoft has finally announced the General Availability (GA) release of PowerShell 7.0. This represents a fairly significant milestone in PowerShell’s history. In this post, I’ll go through some of the history prior to this point, what’s new in this release and how it works in practice.

Read morePowerShell 7.0 – Introduction, History, Installation

Automating Vulnerability Scans – Nexpose/Powershell

One of the common things I’ve seen in automation implemented by infrastructure teams is a lack of rigor around testing. That is to say, code that tests the task that is being automated is actually successful. A script could execute to its end without errors, but that doesn’t necessarily mean it actually did what it was supposed to.

This leads into a concern I’ve seen raised by stakeholders, about visibility of what is happening in an automation pipeline. One of the key stakeholders in this sort of security is the IT Security team, who often want visibility of certain outputs (like virtual machines) to determine if those are secure. In a couple of environments I’ve raised the idea of performing automated vulnerability scans on newly provisioned assets, as a way of ensuring what is delivered is at an acceptable level. By automating this task, we place no extra burden on those involved and ensure consistency.

Read moreAutomating Vulnerability Scans – Nexpose/Powershell

vCenter 6.7 Update 2 – Code Capture

One of the very cool new features that came with the latest vCenter update is Code Capture. This feature allows you to “record” actions in the HTML 5 web client. When the “recording” is ended, Code Capture will generate PowerCLI.NET code. For those who used Exchange 2007, you may remember a similar feature in the GUI management console. At the end of each wizard, there was a summary of PowerShell code that would perform the same task you just finished.

Code Capture has been around for a while as part of the HTML 5 Client Web Fling. However, at the time, it was not appropriate for production use. With the feature being included in 6.7 Update 2, it now is appropriate for use.

Read morevCenter 6.7 Update 2 – Code Capture

vRealize Orchestrator – PowerShell Hosts

PowerShell Hosts are one of the types of endpoint available in vRealize Orchestrator’s Inventory. By having a PowerShell Host, you can leverage the breadth of PowerShell functionality from within your vRealize Orchestrator workflows. In this article, I’ll run through adding a PowerShell Host as well as some considerations from a technical and security point of view.

Adding A PowerShell Host

vRealize Orchestrator has a built-in Workflow for adding a Host under Library > PowerShell > Configuration. Run the “Add a PowerShell host” Workflow to start it. The opening interface is below:

First page of the “Add a PowerShell Host” workflow

Read morevRealize Orchestrator – PowerShell Hosts

SQL As A Service Proof of Concept with SQL 2012 and vRealize Automation

Standing up a redundant/highly available database infrastructure can be one of the more complicated pieces of work.  Doing it by hand is a long process with any points where errors could happen.  It was with this in mind that I decided to use this as my first “project” with vRealize Automation.

A Brief History of SQL Server High Availability

When discussing redundancy or high availability (HA) for databases, there’s two distinct outcomes – firstly to ensure the continued delivery of the service in the event of infrastructure failure (the actual HA part) and secondly to ensure the data is kept in an orderly fashion (data integrity, no loss of data, etc).  Where these two activities happen depend on the technology used.

In older versions of SQL Server, these outcomes were achieved using SQL Clustering.  In SQL Clustering, the HA function was achieved at the server level by having 2 or more servers, while data integrity was maintained by the database residing on shared storage.

Read moreSQL As A Service Proof of Concept with SQL 2012 and vRealize Automation

Windows 7 Remote Assist Wrapper Script

One of the functionality changes in Windows 7 was to Remote Assistance. In XP, you got a nice GUI to input the machine name or IP address of the target machine. In Windows 7, this was changed in a way where it was difficult to do this. You could do it via the command line. As an academic exercise I wanted to create a graphical wrapper for this that duplicated the XP Remote Assistance experience for service desk.

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

#endregion

#region Post-Constructor Custom Code

#endregion

#region Form Creation
#Warning: It is recommended that changes inside this region be handled using the ScriptForm Designer.
#When working with the ScriptForm designer this region and any changes within may be overwritten.
#~~< form1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$form1 = New-Object System.Windows.Forms.Form
$form1.Text = "ASG Remote Assistance"
#~~< btnStartRA >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$btnStartRA = New-Object System.Windows.Forms.Button
$btnStartRA.Location = New-Object System.Drawing.Point(13, 219)
$btnStartRA.Size = New-Object System.Drawing.Size(230, 23)
$btnStartRA.TabIndex = 4
$btnStartRA.Text = "Start Remote Assistance"
$btnStartRA.UseVisualStyleBackColor = $true
$btnStartRA.Enabled = $false
$btnStartRA.Add_Click({ StartRA })
#~~< lstCompInfo >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$lstCompInfo = New-Object System.Windows.Forms.ListBox
$lstCompInfo.FormattingEnabled = $true
$lstCompInfo.Location = New-Object System.Drawing.Point(13, 86)
$lstCompInfo.SelectedIndex = -1
$lstCompInfo.Size = New-Object System.Drawing.Size(259, 108)
$lstCompInfo.TabIndex = 3
#$lstCompInfo.Text = ""
#~~< btnConnect >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$btnConnect = New-Object System.Windows.Forms.Button
$btnConnect.Location = New-Object System.Drawing.Point(197, 37)
$btnConnect.Size = New-Object System.Drawing.Size(75, 23)
$btnConnect.TabIndex = 2
$btnConnect.Text = "Connect"
$btnConnect.UseVisualStyleBackColor = $true
#$btnConnect.Add_Click({ $lstCompInfo.Items.Add("This is a test") })
$btnConnect.Add_Click({ GetDetails })
#~~< txtCompName >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$txtCompName = New-Object System.Windows.Forms.TextBox
$txtCompName.Location = New-Object System.Drawing.Point(13, 39)
$txtCompName.Size = New-Object System.Drawing.Size(168, 20)
$txtCompName.TabIndex = 1
$txtCompName.Text = ""
#~~< Label1 >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$Label1 = New-Object System.Windows.Forms.Label
$Label1.Location = New-Object System.Drawing.Point(13, 13)
$Label1.Size = New-Object System.Drawing.Size(215, 23)
$Label1.TabIndex = 0
$Label1.Text = "Enter Computer Name or IP Address:"
$form1.Controls.Add($btnStartRA)
$form1.Controls.Add($lstCompInfo)
$form1.Controls.Add($btnConnect)
$form1.Controls.Add($txtCompName)
$form1.Controls.Add($Label1)

#endregion

#region Custom Code

#endregion

#region Event Loop

function Main{
[System.Windows.Forms.Application]::EnableVisualStyles()
[System.Windows.Forms.Application]::Run($form1)
}

function GetDetails
{
$strComputer = $txtCompName.Text
$strConnStatus = test-connection -computername $strComputer -quiet

if ($strConnStatus -eq $true)
{
# connection worked, continue script
$lstCompInfo.Items.Add("Connection successful...")
$objUsername = gwmi -computer $strComputer Win32_ComputerSystem | select username, model
$strUserName = $objUsername.Username
$strModelName = $objUsername.Model
$lstCompInfo.Items.Add("Current User is $strUserName")
$lstCompInfo.Items.Add("The target computer is a $strModelName")
$btnStartRA.Enabled = $true
$btnStartRA.Text = "Start Remote Assistance for $strComputer"

}
else
{
# connection failed
#Write-Host "Connection failed with status "
$lstCompInfo.Items.Add("Connection failed.")
$btnStartRA.Enabled = $false
#$strConnStatus | select *
}

}
function StartRA
{
$RAconName = $txtCompName.Text
$lstCompInfo.Items.Add("Attempting to connect to $RAconName" )
cmd /c msra /offerRA $RAconName
}

#endregion

#endregion

#region Event Handlers

Main #This call must remain below all other event functions

#endregion

Some of the lines are note are:

  • Line 24 – The Add_Click will call the function that performs the Remote Assistance connection
  • Line 76 – The script performs a test to see if the system name is responding
  • Line 87 – As part of the IF…THEN statement, if the connection status is true, the connect button is enabled by this line.
  • Line 106 – This line performs the command line version of the Remote Assistance connection, using the supplied computer name in the command

Windows 7 SOE – Reset Computer Groups Script

The application deployment setup in SCCM 2007 means you have to tend towards application deployment based on a user’s computer rather than the user’s account. One method of doing this is to have the computer in security groups that relate to collections to deploy the applications. For example, you may have a security group called “SCCM_Viso2010” to deploy Visio 2010. Where this becomes an issue is when you reimage the machine, you need a method of resetting the machine back to a default state so it doesn’t recieve those extra apps again. The script below was designed to achieve this.

add-pssnapin quest.activeroles.admanagement

write-host "Getting SID, GUID and DN for $env:computername"
$strComputer = get-qadcomputer $env:computername | select sid,guid,dn

write-host "Getting groups for $env:computername"
$strComputerGroups = get-qadmemberof $strComputer.SID

foreach ($obj in $strComputerGroups) {
if ($obj.Name -eq "Domain Computers")
{
write-host "This is the default group, do nothing"
}
else
{
write-host "The group $obj is a non-standard group"
remove-qadgroupmember -identity $obj -member $strComputer.SID
}
}

# Removing Quest AD snapin
remove-pssnapin quest.activeroles.admanagement

The behaviour of the script is to remove any group that isn’t the default group of “Domain Computers”. Like the OU move script, it utilises the Quest AD cmdlets.

Bitnami