Tag Archives: PowerShell

Monitoring processes inside a vm with PowerCLI

As part of a large scale data analysis project I was working on recently I used Horizon View and Instant clones to allow me to deploy hundreds of VMs based on my original templated VM which had my app I wanted to use to take in the data, transform it and then return a result. Its important to note that this app was never written to work in a batch mode, it literally took one input and gave an output based on a number of factors.

Whilst this post is not about the benefits of Instant Clones, let me tell you, once I had the original template VM working correctly and optimized for performance it worked like a charm, there is something to be said for the simplicity and efficiency of instant clones and the memory sharing techniques it uses to be able to run hundreds of essentially the same VM.

Once I had these VMs deployed via Horizon I could easily send a job to each VM and tell it to run the job, as these jobs however took an indeterminate amount of time to crunch the data, I needed a way to monitor them and let me know when all the jobs had finished on all the VMs so I could pull the data to analyze it.

First I went down the route of using Invoke-VMScript to hook inside the VM’s and see if the process was running, this however took a long time to complete on 100’s of virtual machines and the monitoring job often took over 20 minutes to monitor the VMs and tell me if the job was completed… far too long for what I needed. So after some googling I learned from my good friend William Lam that there was a new API available that through VMtools would update the GuestInfo with the processes running inside the VM on a configurable timely basis (see his post here), this allowed me to essentially push the information externally to the VM Guest Operating system and grab the info when I needed it to see if my process was running.

William had also written a handy function which I adjusted to work with an array of VMs and tell me if the process was running.

Using these new found skills I was easily able to write a function that allowed me to pull the running processes from the VMs and remove them from the list as that process finished inside the VM, for the icing on the cake I even got it to update me in slack on how it was doing 😉

So i thought I would share this script and encourage you to think about using this way which is much easier and a more performant way to pull the results of the running processes..

Monitoring Script

Function Send-SlackMessage ($Channel = "#MyProjectChannel", $Message) {
        
    $payload = @{
        "channel"    = $Channel
        "icon_emoji" = ":datacenter:"
        "text"       = $Message
        "username"   = "DC Script"
    }

    Invoke-WebRequest `
        -UseBasicParsing `
        -Body (ConvertTo-Json -Compress -InputObject $payload) `
        -Method Post `
        -Uri "https://myslackhookurl" | Out-Null
}

Function Get-VMApplicationInfo {
<#
    .DESCRIPTION Retrieves discovered applications running inside of a VM
    .NOTES  Author:  William Lam
    .NOTES  Site:    www.virtuallyghetto.com
    .NOTES  Reference: http://www.virtuallyghetto.com/2019/12/application-discovery-in-vsphere-with-vmware-tools-11.html
    .PARAMETER VM
        VM Object
    .PARAMETER Output
        CSV or JSON output file
    .EXAMPLE
        Get-VMApplicationInfo -VM (Get-VM "DC-01")
    .EXAMPLE
        Get-VMApplicationInfo -VM (Get-VM "DC-01") -UniqueOnly
    .EXAMPLE
        Get-VMApplicationInfo -VM (Get-VM "DC-01") -Output CSV
    .EXAMPLE
        Get-VMApplicationInfo -VM (Get-VM "DC-01") -Output JSON
#>
    param(
        [Parameter(Mandatory=$true)]$VM,
        [Parameter(Mandatory=$false)][ValidateSet("CSV","JSON")][String]$Output,
        [Parameter(Mandatory=$false)][Switch]$UniqueOnly
    )

    $appInfoValue = (Get-AdvancedSetting -Entity $VM -Name "guestinfo.appInfo").Value

    if($appInfoValue -eq $null) {
        Write-Host "Application Discovery has not been enabled for this VM"
    } else {
        $appInfo = $appInfoValue | ConvertFrom-Json
        $appUpdateVersion = $appInfo.updateCounter

        if($UniqueOnly) {
            $results = $appInfo.applications | Sort-Object -Property a -Unique| Select-Object @{Name="Application";e={$_.a}},@{Name="Version";e={$_.v}}
        } else {
            $results = $appInfo.applications | Sort-Object -Property a | Select-Object @{Name="Application";e={$_.a}},@{Name="Version";e={$_.v}}
        }

        Write-verbose "Application Discovery Time: $($appInfo.publishTime)"
        if($Output -eq "CSV") {
            $fileOutputName = "$($VM.name)-version-$($appUpdateVersion)-apps.csv"

            Write-Host "`tSaving output to $fileOutputName"
            ($appInfo.applications) | ConvertTo-Csv | Out-File -FilePath "$fileOutputName"
        } elseif ($Output -eq "JSON") {
            $fileOutputName = "$($VM.name)-version-$($appUpdateVersion)-apps.json"

            Write-Host "`tSaving output to $fileOutputName"
            ($appInfo.applications) | ConvertTo-Json | Out-File -FilePath "$fileOutputName"
        } else {
            $results
        }
    }
}


Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ErrorAction SilentlyContinue -Confirm:$false -DisplayDeprecationWarnings $false | out-null
$ProgressPreference = 'SilentlyContinue'


Connect-viserver vcsa-01a.myenv.local -username Administrator@vsphere.local -password VMware1! | Out-Null
$vms = get-vm InstantCloneVM* | Where-Object {$_.PowerState -eq "PoweredOn"} | Sort-Object Name
Send-Slackmessage -message "Monitor Job Started" 
do {
    foreach ($vm in $vms) {
        Write-Host "Checking $VM status..."
        $result = Get-VMApplicationInfo -VM $VM| Where { $_.Application -eq "MyAppProcess.exe" }
        if (!$result){
            Write-Host "Removing $vm as it has completed"
            $vms = $vms | where { $_.Name -ne $vm.name}
        } else {
            Write-Host "$vm still running"
        }
        if (($vms.count -lt 10) -and (! $sentmail)){
            Send-Slackmessage -message "Less than 10 Sigma VMs left"
            $sentmail = $true
        }
    }
    if (! ($oldnumvms -eq ($vms.count))){
        Send-Slackmessage -message "$($vms.count) VMs still running"
    }
    start-sleep -s 30
    $oldnumvms = $vms.count
}
while ($vms)
Send-Slackmessage -message  "All Jobs Completed"

New Year, New Look vCheck

Its been a while since I blogged about vCheck but that doesn’t mean there has been lots of work ongoing with the project, in fact there has been multiple releases and hundreds of pull requests with great new plugins checking for even more issues with your vCenter and lots of bug fixes, in fact this project and the community updating and using it is awesome, here are some the current stats:

  • 954 Commits
  • 64 Contributors (Thanks to all here)
  • 66 Open Issues and 269 Closed Issues

Whats more, one of the most recent releases 6.25 here includes a great new look, the new look is based upon VMwares Clarity framework and personally I think it looks fantastic as you can see below:

vCheck Clarity

Also available (currently in the dev branch) is the brand new dark version of the theme as seen below:

vCheck Clarity Dark

Download for free now!

Download the latest version here:  https://github.com/alanrenouf/vCheck-vSphere/archive/master.zip

And the dev branch version here: https://github.com/alanrenouf/vCheck-vSphere/archive/dev.zip

 

Is your PowerShell Core up to date?

I have been using PowerShell Core for a while now, its great not to have to spin up a windows VM every time I want to work with PowerShell on Mac!

Let’s face it though, not everything is there at the moment, so every time there is an update I want to know.  The Microsoft team are doing a great job of updating PowerShell Core and it seems like every time I go check there is a new version which fixes bug or introduces new cmdlets.

This does however mean I need to constantly go check the releases page or keep an eye on twitter to see when new releases come out.. until now!

The following function is a 5 minute function I wrote to keep on top of the updates, I have placed it in my PowerShell profile and now every time I launch PowerShell from my mac it checks and tells me if there is a new version as below:

Code

Just use the following code and paste it into the file located at $profile and every time you launch PowerShell it will go check for you!

Function Get-PowerShellRelease {
    #Using this to get rid of the nasty output Invoke-WebRequest gives you in PowerShell on the Mac
    $progress = $ProgressPreference
    $ProgressPreference = "SilentlyContinue"
    $JSON = Invoke-WebRequest "https://api.github.com/repos/powershell/powershell/releases/latest"| ConvertFrom-Json
    If ($psversiontable.GitCommitId) {
        If ($JSON.tag_name -ne $psversiontable.GitCommitId) {
            Write-Output "New version of PowerShell available!"
            $JSON.body
        } Else {
            "PowerShell is currently up to date!"
        }
    }
    $ProgressPreference = $progress
}

Get-PowerShellRelease

Check your Cisco UCS environment for issues with vCheck

Do you use Cisco UCS? If you do then this will interest you.  vCheck is basically a FREE HTML reporting framework that was written to originally check a VMware environment but as it uses PowerShell it is easily adjustable to check anything that is PowerShell enabled, like for instance…. UCS environments.

One of the objectives of me putting vCheck into github was the hope that people would be able to easily pick up the framework and create their own projects to check other PowerShell enabled products, this has already been done with a number of different products as listed below:

Download Link Github Project Example Output Page
vCheck for vSphere Click here Click here
vCheck for Exchange 2010 Click here Click here
vCheck for vCD Click here Coming soon
vCheck for SCVMM Click here Click here
vCD Audit script Click here Click here
vCloud Air Audit Click here Click here

And now you can add Cisco UCS to the list, Joshua Barton has done a great job of using the framework to create a new vCheck edition that will enable UCS Admins to run a check on their systems and bring back any known issues that may be a problem.  Don’t forget, this as with all the other vCheck editions is a community project so you can add your own checks very easily in the plugins folder, if you need help then check out this early video which was recorded of me showing how to easily do that.

So what does it check currently?

  • General Details
  • Recent Faults
  • Unassociated Profiles
  • High Pool Utilization
  • Fault Retention Policy
  • Default Adapter Behavior
  • Non-Functioning Enabled Ports
  • Switching Mode
  • Inactive Servers
  • Uplink Flow Control
  • LACP Policies
  • UDLP Policies
  • Maintenance Policies
  • Default Pool Schema
  • Chassis Discovery Policy
  • Power Policy
  • SEL Policy

What does it look like?

As you can see, the html file that is created, which can also be scheduled to be sent to you as an email looks pretty awesome:

UCS-vCheck

 

The full example can be seen here: http://www.foobartn.com/assets/examples/example-report.html

How do I download this and get involved?

Visit the Github Rep here: https://github.com/FooBartn/vCheck-UCS/tree/dev

Download it directly from here: https://github.com/FooBartn/vCheck-UCS/archive/dev.zip

And make sure you thanks Joshua on twitter via @FooBartn

VMworld 2015–San Francisco–PowerCLI Session

Firstly, I want to say I had a blast at VMworld SFO this year, it was a fantastic show and it really felt like everyone was buzzing with excitement and interest in VMware, the announcements, the partners and just about everything else that was going on.  I think this may be one of my favorite years to date.

 

On top of the general excitement there was of course the awesome group discussions, meet the experts, sessions and customer meetings which I took part in, I was lucky enough to present on some awesome topics this year, the normal PowerCLI deep dive I give with Luc (see below) and also a fantastic new technology called Instant Clone (AKA VMfork). The instant clone presentation is not yet available but for those who are into PowerCLI I wanted to let you know that Luc and my session was made available for everyone to view via PowerCLI, including the information we gave on best practices and also a technical preview of PowerCLI.

 

If you are going to VMworld Barcelona do not worry, we are already adjusting our session to be even better with more best practices and even more information on the awesomeness of PowerCLI.  Well worth attending and watching this as well.

 

PowerCLI 6.0 and vCloud Air

One of the great enhancements in the recently released PowerCLI 6.0 is the ability to connect to vCloud Air and vCloud Air Networks, Massimo has already started doing a great write-up on these over at the vCloud Air Blog here.

So why is this a great enhancement?  Well any new area that supports PowerCLI or PowerShell is a great enhancement to me, I mean being able to use PowerCLI to take your automation one step further is always a bonus!  I love the fact that we can now from one shell manage our vSphere environments and our vCloud Air environments for troubleshooting, reporting, provisioning and general automation.  This also goes along with VMware’s key focus of being able to use the same tools to seamlessly extend your datacenter into the cloud by allowing management with the same tools you use to manage your vSphere environment.  On top of this, the ability to manipulate data in both areas and integrate scripts between your on-premises datacenter and your vCloud Air datacenter opens up some great possibilities, imagine being able to automatically spin up new VMs in the cloud when a script works out you need more resources and automatically adding and removing these to a load balancer etc. True hybrid computing!

 

Anyway, I could come up with use cases for this all day but lets get down to business and explain how to get started, firstly, read Massimo’s great posts here, secondly lets talk about connecting, there are a couple of tricks I have been using for a while now in vSphere that are transferable skills and also work in the vCloud Air environment that make it more convenient to use.

Connecting to vCloud Air with Username and Password

Firstly its easy to connect to vCloud Air and specify your username and password, this would look like the following:

image

The first thing you will notice is that we didn’t specify a server to connect to, with the Connect-PIServer cmdlet if no server is specified it uses the default of vchs.vmware.com, one less parameter to specify but what id I don’t want to give my username and password as part of the script?  What if I am giving a demo and I don’t want people to see my password?

Connecting to vCloud Air with interactive prompt

If we want to specify a username and password interactively we can just use Connect-PIServer, this is assuming you have not stored credentials in the VICredentialStore, which we will cover next.

image

Storing your credentials

This is the method I use the most, with this method I can have a highly secure random password and not need to remember it to connect to vCloud Air, this uses the same method of saving credentials that we use for vSphere environments and even the same secure file.  There are a couple of ways we can do this, the first is with the –SaveCredntials parameter as below:

image

Or use the New-VICredentialStoreItem cmdlet to create a credential item for vchs.vmware.com

image

Once you have the credentials stored you can manage them with the Set and Remove –VICredentialStoreItem cmdlets.

Now this has been done if we do not specify a credential it will check the VICredentialStore for credentials and use these so connecting to vCloud Air now becomes a single cmdlet:

image

Listing the Datacenters and Connecting

Now we have made the initial connection to vCloud Air we can easily list the datacenters we have access to and connect to them, firstly lets list the vCloud Air Datacenters with Get-PIDatacenter and then connect to them with Connect-PIDatacenter (which is actually an alias to the Connect-CIServer cmdlet).

image

Now you have some tips and can see how easy it is to connect to vCloud Air, in future posts I will make use of this connection to start automating vCloud Air and providing PowerCLI enabled resources to use with vCloud Air.

Retrieving VM Metrics from vCloud Air

Recently I was working with vCloud air and PowerCLI and was asked if there was a way to retrieve the statics of a VM and export these to get a better idea of the utilization of that VM.

Working with vCloud Air and the API through the PowerCLI cmdlets I was able to use the GetMetricsCurrent() and GetMetricsHistoric() to retrieve both the current VM Metrics and also the historic metrics of a VM.  The type of metrics and their values is described here.

VM Current Metrics

Current metrics are instantaneous values collected at the time the request is processed. The GetMetricsCurrent() method retrieves a list of current metric values, one for each category. I put this into a handy function which can be found at the end of this post, with this function we can pass vCloud AIR VMs into it and retrieve the current metrics.

image

VM Historic Metrics

Historic metrics are collected and stored for 14 days. A call to the GetMetricsCurrent() method retrieves the past 24 hours of metric history.  again I created a function that allows us to select a VM (or multiple) and get the historic data for this VM.

image

You will see that this time the method returns a collection of results in the Sample entry, we can then expand this to return the results for the metric over the last 24 hours.

image

Creating a VM Statistical report

Of course with this being PowerShell we can add value to these results, I mean who wants to look at a long list of numbers, wouldn’t you rather see a pretty graph?  We can easily use Luc’s great Export-XLSX function to export the results for each metric straight into Excel and even create us a nice graph for each statistic:

image

image

The Functions

Make sure you download Lucs Export-Xlsx function from here, and below are the functions I used to retrieve this information from vCloud Air.

Function Get-CIVMMetric {
	Param (
		[Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
		$CIVM
	)
	Process {
		foreach ($VM in $CIVM) {
			If ($VM.Status -ne "PoweredOn") {
				Write-Host "$VM must be Powered On to retrieve metrics"
				exit
			} Else {
				$Metrics = $CIVM.ExtensionData.GetMetricsCurrent()
				$metrics.Metric
			}
		}
	}
}

Function Get-CIVMHistoricalMetric {
	Param (
		[Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
		$CIVM
	)
	Process {
		foreach ($VM in $CIVM) {
			If ($VM.Status -ne "PoweredOn") {
				Write-Host "$VM must be Powered On to retrieve metrics"
				exit
			} Else {
				$Metrics = $CIVM.ExtensionData.GetMetricsHistoric()
				$metrics.MetricSeries
			}
		}
	}
}

# Get the Current Metrics for the VM
Get-CIVM sql-w-01a | Get-CIVMMetric

# List the Available Historical Metrics for the VM
Get-CIVM sql-w-01a | Get-CIVMHistoricalMetric

# Get the CPU Historical Metrics
Get-CIVM sql-w-01a | Get-CIVMHistoricalMetric | Where {$_.Name -eq "cpu.usage.average"} | Select -ExpandProperty Sample

$VMName = "sql-w-01a"
Foreach ($stat in (Get-CIVM $VMName | Get-CIVMHistoricalMetric)){
    Foreach ($Entry in $Stat) {
        $Data = $Entry.Sample | Select Timestamp, @{Name=($Entry.Name);Expression={$_.Value}}
        Export-Xlsx $Data C:\Temp\$VMName.xlsx -WorksheetName ($Entry.Name) -ChartType "xlXYScatterSmooth" -AppendWorksheet
    }
}

Automated deployment of vCloud Networking and Security 5.5

A while ago I posted a PowerCLI method for deploying vShield 5.0 which can be found here, as mentioned in the comments of that post this did not work for vCNS 5.5, this is because the process of deploying it changed and actually became a lot neater than what it was before.  Before we had to reach inside the guest OS and mess around with configuration files.  In the 5.5 release the vCNS team made some changes to make this easier for people to automatically deploy,

 

I actually wrote this a while ago and forgot about it until recently when I was asked if it could be done, this was a great reminder for me to post the code for others to use.

 

You will see in the code that we need to specify some variables at the start of the script, you will see in the code that you need to specify a cluster to deploy vCNS to, as part of this script it automatically picks a random host and a shared datastore which has enough room to deploy the appliance to, this is just an example and can be changed to your requirements as needed – I was just having fun with a kind of automated placement Winking smile

You will need PowerCLI 5.8 R1 for this and don’t forget, once vShield has been deployed you can easily take the configuration further by using the vShield module I created here.   For other examples of deployment scripts for VMware appliances check out the repo here and contribute!

Example output

image

Code

Automating Tags and Tag Category creation and assignment with PowerCLI

Fimageor a couple of releases now PowerCLI has been able to work with vSphere Tags, A tag is a label that you can apply to objects in the vSphere inventory.

After creating a tag, you can assign that tag to a category. Categories allow you to group related tags together. When you define a category, you can also specify the type of objects to which its tags can be applied to and whether more than one tag in the category can be applied to an object.

For example, if you want to tag your virtual machines by the owner, you can create a category called “Owner” and specify that it applies to virtual machines only and that only a single tag can be applied to a virtual machine at any time. The tags in this category could be Alan, John or Fred etc.

I have had a few people ask me how they can use PowerCLI to work with external systems, CMDBs, databases or even just a CSV file.

One example of this is where a company could have various information about hosts or datastores or virtual machines, like the project that purchased these, a cost code or an owner.  This data is generally stored somewhere else but it would be great to see this information straight in the vSphere Web Client where you manage the objects so that you can instantly contact the owner or work out which project the object is being used for etc.

The below video shows how we can use PowerCLI and this generic script I created to import the data, create the tags and tag categories and assign them to the machines, it uses a csv as input but this could obviously be changed to anything which can be read in PowerShell, like a API, database, application etc etc.

Automating tags and tag categories video

Example Script

This script is the script I created as an example which relates each of the items in the Name column to an object in the inventory then for each of the other column headers it will create a category and then the tags that are under the categories, once this has been done it will apply the tags to the objects in the Name column.

Connect-viserver myvc.corp.local -user administrator@vsphere.local -pass Pa$$w0rd
$CMDBInfo = Import-CSV C:\Software\cmdbinfo.csv

# Get the header names to use as tag category names
$TagCatNames = $cmdbinfo | Get-Member | Where {$_.MemberType -eq "NoteProperty"} | Select -Expand Name

# Create the Tag Category if it doesnt exist
Foreach ($Name in ($TagCatNames | Where {$_ -ne "Name"})) {
    if (-Not (Get-TagCategory $Name -ea SilentlyContinue)) {
        Write-Host "Creating Tag Category $Name"
        New-TagCategory -Name $Name -Description "$Name from CMDB" | Out-Null
        
        # Create Tags under the Tag Categories
        $UniqueTags = $cmdbinfo | Select -expand $name | Get-Unique
        Foreach ($Tag in $UniqueTags) {
            if (-Not (Get-Tag $Tag -ea SilentlyContinue)) {
                Write-Host "..Creating Tag under $Name of $Tag"
                New-Tag -Name $Tag -Category $name -Description "$Tag from CMDB" | Out-Null
            }
            # Assign the Tags to the VMs/Hosts
            $cmdbinfo | Where {$_.($Name) -eq $Tag} | Foreach {
                Write-Host ".... Assigning $Tag in Category of $Name to $($_.Name)"
                $TagAssignment = Get-Tag -Category $Name -name $Tag
                New-TagAssignment -entity $($_.Name) -Tag $Tagassignment | Out-Null
            }
        }          
    }
}

PowerShell User Group–Campbell–CA–Nov 5th

Are you interested in PowerShell? Do you want free Pizza? If the answer to either of these questions is YES then join us!

Are you in the Campbell, California area on 5th Nov 2014?

I will be presenting about PowerCLI and covering the following areas:

  • Introduction to managing VMware products with PowerShell
  • Reporting
  • Deployment
  • Automation
  • Integration
  • Community
  • Where are VMware headed?
  • Question time!

If you are not interested in managing VMware products with PowerShell then attend anyway, we will no doubt reference lots of PowerShell general tips and tricks and definitely have some great conversations about PowerShell in general.

When and Where?

Wednesday, November 5, 2014

6:00 PM to 9:00 PM

 

Groupware Corporate Office

550 Division Street, Campbell, CA (map)

RSVP

Make sure you sign up here.