If you ever have experienced that after your vCenter server reboots – due to Windows updates, the “VMware VirtualCenter Server” service is not starting?
I have seen it a few times and every time it’s during a weekend
So to make sure your vCenter service (or other) is always running you could use this powershell script to check if a service is running, and if not start it.
To make sure you know if the service wasn’t started after a reboot or other cause, I have added a mail function to the script
function FuncCheckService{
param($ServiceName)
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne "Running"){
Start-Service $ServiceName
FuncMail -To "to-email@domain.com" -From "from-mail@domain.com" -Subject "Servername : ($ServiceName) service started." -Body "Service $ServiceName started" -smtpServer "relay.mailserver.com"
}
}
function FuncMail {
#param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
param($To, $From, $Subject, $Body, $smtpServer)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $From
$msg.To.Add($To)
$msg.Subject = $Subject
$msg.IsBodyHtml = 1
$msg.Body = $Body
$smtp.Send($msg)
}
FuncCheckService -ServiceName "VMware VirtualCenter Server"
Create a PS1 file and schedule it to run every 15 or 30 minutes.
It works great and is simple….
If you want to configure a hosts NTP server list through PowerCLI you have a few cmdlet at your disposal.
Get a list of NTP servers on a host.
Get-VMHostNtpServer -VMHost "esx01.lab.local"
To remove a specific NTP server from a host NTP server list.
Remove-VMHostNtpServer -VMHost "esx01.lab.local" -NtpServer '127.127.1.0' -Confirm:$false
To remove all NTP servers on a hosts NTP server list.
$arrNTPList = Get-VMHostNtpServer -VMHost "esx01.lab.local" Remove-VMHostNtpServer -VMHost "esx01.lab.local" -NtpServer $arrNTPList -Confirm:$false
To add a single NTP server to a hosts NTP server list.
Add-VMHostNtpServer -VMHost "esx01.lab.local" -NtpServer "dk.pool.ntp.org" -Confirm:$false
To add a a list of NTP servers to a hosts NTP server list.
$arrNTPServers = ("dk.pool.ntp.org","de.pool.ntp.org","us.pool.ntp.org")
Add-VMHostNtpServer -VMHost "esx01.lab.local" -NtpServer $arrNTPServers -Confirm:$false
To set the NTP deamon (service) to start automatic.
Set-VMHostService -HostService (Get-VMHostservice -VMHost (Get-VMHost "esx01.lab.local") | Where-Object {$_.key -eq "ntpd"}) -Policy "Automatic"
Open firewall to allow the NTP deamon to communicate with the NTP server.
Get-VmhostFirewallException -VMHost "esx01.lab.local" -Name "NTP Client" | Set-VMHostFirewallException -enabled:$true
To restart the NTP deamon (service) after you have configured it – without restarting the host.
$ntpd = Get-VMHostService -VMHost "esx01.lab.local" | where {$_.Key -eq 'ntpd'}
Restart-VMHostService $ntpd -Confirm:$false
Since Vizioncore came out with vRanger 4.x, last year, I been working on porting the VBS script “vRanger Script version 2.0” to Powershell.
During this time I have found several bugs/missing functionality in the vAPI.
Vizioncore have corrected the bugs with new releases of vRanger.
The first vRanger version where all vAPI cmdlets worked in was version 4.2.3.
Porting the script from VBS presented me with a few challenges.
A few words on the scrips functionality.
When I started coding the script, I found, that if I used functions for all functionality the script was easier to read. Using functions also supplied me with the opportunity of reusing functions – less work
.
Some of the functions was created using examples posted and mailed by Scott Harold from Quest and TheVesi./vEcoShell.
Prerequirements
The script can be downloaded here.
A quick overview of the functions.
Include the right PSSnapins
function LoadSnapin{
Add-PSSnapin vRanger.API.PowerShell -ErrorAction SilentlyContinue
Add-PSSnapin vmware.VimAutomation.core -ErrorAction SilentlyContinue
}
LoadSnapin
Delete all previous savepoints – from the repository.
function RemoveAllSavePoints{
param ($RASP_RepoName)
$RASP_repoID = Get-Repository | where {$_.Name -eq $RASP_RepoName}
$RASP_SPlist = Get-RepositorySavePoint -ID $RASP_repoID.Id
foreach ($RASP_SP in $RASP_SPlist){
#write $RASP_SP
Remove-SavePoint -SavePointsToRemove $RASP_SP
}
}
RemoveAllSavePoints "Remote-Location"
Is a backup job exist with the same name as the one to create – delete it.
function Del-vRangerBackupJobs {
param ($delJobName)
$delTemplateID = Get-JobTemplate | where {$_.JobName -eq $delJobName}
# Verify that a BackupJob named XXX is present before deleting it.
if ($delTemplateID){
#write $delTemplateID.JobName
Remove-JobTemplate -id $delTemplateID.Id
}
}
Del-vRangerBackupJobs "$Wednesday-Even"
Create the list of VMs to exclude.
function Filter-VMbyCF {
param ($customF, $val)
foreach ($vm in $vmlist) {
$vm.CustomFields | ForEach-Object {
$cf = $_
if ($_.Key -like $customF -and $_.Value -like $val){
return $vm.name
}
}
}
}
function New-vRangerExcludeList {
param ($exclude, $include)
$excludeArray = @()
$exclude | ForEach-Object {
if ($include -notcontains $_.Name){
$excludeArray += ($_.Config.Uuid)
}
}
return $excludeArray
}
$vmlist = Get-VM
$tmplist = Get-Template
$vmlist= $vmlist + $tmplist
$vmFilter = Filter-VMbyCF $customField $CFValue
$vmlistview = $vmlist | Get-View
$excludeList = New-vRangerExcludeList -exclude $vmlistview -include $vmFilter
Create the new backup job.
function New-vRangerBackupJob {
param ($customJobName, $customCFValue, $customFieldName, $customRepoName, $customExcludeList, $customEmail)
$jobDesc = "This backup job is created by Logica for use in DR. All VMs with a Custom Field labeled: $customFieldName with a value of: $customCFValue will be backed up"
$jobEntity = Get-InventoryEntity -Type VirtualCenter
$jobRepos = Get-Repository | where {$_.Name -eq $customRepoName}
$jobFlag = New-BackupFlag -CheckDestinationFreeSpace:$true -UseCompression:$true -PerformNetworkBackupOnFailure:$true
# Check if all disks or just disk 0
if ($customJobName -like "*-All*"){
#write "All - Disks"
#Add-BackupJobTemplate -JobName $customJobName -JobDescription $jobDesc -JobEntity $jobEntity -ExcludedVMList $customExcludeList -NotificationList $email -TargetRepository $jobRepos -Flags $jobFlag -NumberOfSavePoints 1 -SpaceSavingTechnologyTypeFlag None
Add-BackupJobTemplate -JobName $customJobName -JobDescription $jobDesc -JobEntity $jobEntity -ExcludedVMList $customExcludeList -NotificationList $customEmail -TargetRepository $jobRepos -Flags $jobFlag -NumberOfSavePoints 1 -SpaceSavingTechnologyTypeFlag None -SpaceSavingCountThreshold 6 -SpaceSavingPercentSizeThreshold 50
}
else{
#write "Only Disk 0"
#Add-BackupJobTemplate -JobName $customJobName -JobDescription $jobDesc -JobEntity $jobEntity -ExcludedVMList $customExcludeList -NotificationList $email -IncludedDiskList 0 -TargetRepository $jobRepos -Flags $jobFlag -NumberOfSavePoints 1 -SpaceSavingTechnologyTypeFlag None
Add-BackupJobTemplate -JobName $customJobName -JobDescription $jobDesc -JobEntity $jobEntity -ExcludedVMList $customExcludeList -NotificationList $customEmail -IncludedDiskList 0 -TargetRepository $jobRepos -Flags $jobFlag -NumberOfSavePoints 1 -SpaceSavingTechnologyTypeFlag None -SpaceSavingCountThreshold 6 -SpaceSavingPercentSizeThreshold 50
}
}
New-vRangerBackupJob "Wednesday-Even" "Wednesday-Even" "Backup" "Remote-Location" $excludeList "to@email.com"
Start the backup job.
function Run-BackupJob{
param ($runJobName)
$runTemplateID = Get-TemplateID $runJobName
Run-JobsNow $runTemplateID
}
Run-BackupJob "Wednesday-Even"
Wait for the backup job to finish.
function Get-TemplateID{
param($tmpJobName)
$arrTemplate = get-jobtemplate | where {$_.JobName -eq $tmpJobName}
return $arrTemplate.ID
}
function WaitForJobToFinish{
param ($strWaitJob)
$strCompleted = "NotStarted"
Start-Sleep -Seconds 300 # 5 minutes
$jobTemplates = get-JobTemplate | where {$_.JobName -eq $strWaitJob}
foreach ($job in $jobTemplates){
do{
$tasksinfo = get-job |where {$_.ParentJobTemplateID -eq $job.TemplateVersionID}
foreach ($task in $tasksinfo){
Start-Sleep -Seconds 300 # 5 minutes
$strCompleted = $task.JobState
# Make sure job is running - if not start it...
if ($task.JobState -eq $NULL -or $task.JobState -eq "NotStarted"){
Run-BackupJob $strWaitJob
Start-Sleep -Seconds 120 # 2 minutes
}
}
}
while ($strCompleted -notmatch "Completed")
}
}
WaitForJobToFinish "Wednesday-Even"
Send TSM finished mail.
function FuncMail {
#param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
param($To, $From, $Subject, $Body, $smtpServer)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $From
$msg.To.Add($To)
$msg.Subject = $Subject
$msg.IsBodyHtml = 1
$msg.Body = $Body
$smtp.Send($msg)
}
FuncMail -To "to@email.com" -From "from@email.com" -Subject "vRanger Pro: TSM backup finished" -Body "Your Body" -smtpServer "your.mailserver.com"
A few weeks ago I came across a podcast on http://get-scripting.blogspot.com about Powershell.
I highly recommend that all people using powershell check it out.
Get the latest and the archived podcasts at
http://get-scripting.blogspot.com/search/label/podcast
Today I needed to create a list of all users connected to a vCenter sever through the Client.
And during so I created a few variants
This creates a list of all usernames connected to the vCenter server through a vCenter Client.
$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
$sessMgr = get-view $serviceInstance.Content.sessionManager
foreach ($sess in $sessMgr.SessionList){
write "$($sess.UserName)"
}
If you want to see a witch clients have been idle for 60 minutes try this.
$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
$sessMgr = get-view $serviceInstance.Content.sessionManager
foreach ($sess in $sessMgr.SessionList){
if (($sess.LastActiveTime).addminutes(60) -lt (Get-Date)){
write "$($sess.UserName)"
}
}
If you the want to terminate the sessions that have been inactive for more than 60 minute
$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
$sessMgr = get-view $serviceInstance.Content.sessionManager
$oldSessions = @()
foreach ($sess in $sessMgr.SessionList){
if (($sess.LastActiveTime).addminutes(60) -lt (Get-Date)){
$oldSessions += $sess.Key
}
}
$sessMgr.TerminateSession($oldSessions)
You can modify the hell out of this script to suit your needs and be my guest….
You can download the full script here.
The scripts are based on code found at the PowerCLI community by LucD.
http://communities.vmware.com/message/914858#914858
Last week I attended a Magirus course on administrating you VMware environment using PowerCLI, and below is some of the small scripts I created.
These code sniplets will help you manage your VMware environment and give you some ideas of how powerful the VMware PowerCLI really is.
I’m sure VMware will add even more CMDLETS to the PowerCLI in the feature.
Get the latest PowerCLI here.
A function to load different PSSnapins.
Put it in the beginning of all you Powershell scripts,
to load the different PSSnapin you need.
function LoadSnapin{
param($PSSnapinName)
if (!(Get-PSSnapin | where {$_.Name -eq $PSSnapinName})){
Add-pssnapin -name $PSSnapinName
}
}
LoadSnapin -PSSnapinName "VMware.VimAutomation.Core"
Clone a VM to template.
$VMToClone = "vm_name"
$TemplateName = "TemplateName"
$Datacenter = "Training"
get-vm $VMToClone| stop-vm
New-Template -VM $VMToClone -Name $TemplateName
-Location $(Get-Datacenter $Datacenter)
Convert Template to VM – without changing the name.
$TemplateName = "TemplateName"
Set-Template -Template $(get-template $TemplateName) -ToVM
Convert VM to Template – without changing the name.
$VMtoTemplate = "vm_name"
$vm = Get-VM $VMtoTemplate | Get-View
$vm.MarkAsTemplate()
Deploying a VM from template.
$strNewVMName = "NewVM_01"
$strTemplate = "TemplateName"
$strDestinationHost = "ESX01"
New-VM -Name $strNewVMName -Template $(get-template $strTemplate)
-VMHost $(Get-VMHost $strDestinationHost)
Deploying a VM from template using a Customization Specification and using Thin provisioning.
Make sure the CustomSpec has been created beforehand.
$strNewVMName = "NewVM_01"
$strTemplate = "TemplateName"
$strDestinationHost = "ESX01"
$strCustomSpec = "TEST-CustomSpec"
New-VM -Name $strNewVMName -Template $(get-template $strTemplate)
-VMHost $(Get-VMHost $strDestinationHost) -DiskStorageFormat
Thin -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec)
Moving a VM to a specific folder.
$strDistinationFolder = "MyFolder"
$strDatacenter = "Training"
$VMToMove = "MyVM"
move-vm -VM $(get-vm $VMToMove) -Destination $(Get-Folder
-Name $strDistinationFolder -Location $(Get-Datacenter $strDatacenter))
Copying a file to a Windows VM (With or without network access)
Requires VMware tools to be running.
$VM = get-vm -name "myVM"
$target = "C:\MY_DIR\"
$source = "C:\MY_DIR\test.txt"
Copy-VMGuestFile -Source $source -Destination $target -vm $VM
-LocalToGuest -HostUser "root" -HostPassword "password"
-GuestUser "myVM\administrator" -GuestPassword "password"
-Force:$true
Copying a file from a Windows VM (With or without network access)
Requires VMware tools to be running.
$VM = get-vm -name "myVM"
$target = "C:\MY_DIR\"
$source = "C:\MY_DIR\test.txt"
Copy-VMGuestFile -Source $source -Destination $target -vm $VM
-GuestToLocal -HostUser "root" -HostPassword "password"
-GuestUser "myVM\administrator" -GuestPassword "password"
-Force:$true
Listing the content of “C:\Windows\System32″ from a VM – remotely
$VM = get-vm -name "myVM"
Invoke-VMScript -VM $VM -ScriptText "dir" -HostUser "root"
-HostPassword "password" -GuestUser "myVM\administrator"
-GuestPassword "password"
Run msinfo32 on a guest VM and pipe the output to a TXT file – Using PowerShell.
$VM = get-vm -name "myVM"
$script = '&"$env:ProgramFiles\Common Files\Microsoft Shared\
MSInfo\msinfo32.exe" /report "$env:Tmp\inforeport.txt"'
Invoke-VMScript -VM $VM -ScriptText $script -HostUser "root"
-HostPassword "password" -GuestUser "myVM\administrator"
-GuestPassword "password"
Open the above output file in the guest VM – Using PowerShell.
$VM = get-vm -name "myVM"
$script = '&"notepad.exe" "$env:Tmp\inforeport.txt"'
Invoke-VMScript -VM $VM -ScriptText $script -HostUser "root"
-HostPassword "password" -GuestUser "myVM\administrator"
-GuestPassword "password" -ScriptType Powershell
Run msinfo32 on a guest VM and pipe the output to a TXT file – Using batch commands.
$VM = get-vm -name "myVM"
$script = '&"%programfiles%\Common Files\Microsoft Shared\
MSInfo\msinfo32.exe" /report "%tmp%\inforeport.txt"'
Invoke-VMScript -VM $VM -ScriptText $script -HostUser "root"
-HostPassword "password" -GuestUser "myVM\administrator"
-GuestPassword "password" -ScriptType Bat
Open the above output file in the guest VM – Using batch commands.
$VM = get-vm -name "myVM"
$script = '"notepad.exe" "%Tmp%\inforeport.txt"'
Invoke-VMScript -VM $VM -ScriptText $script -HostUser "root"
-HostPassword "password" -GuestUser "myVM\administrator"
-GuestPassword "password" -ScriptType Bat
Finally everyone outside the closed beta is now able to get hands on with the cool application Project Onyx.
Thanks to Carter Shanklin
Project overview – Got it from http://www.ntpro.nl/blog/archives/1330-Project-Onyx-Alpha-Release.html
Onyx is a standalone application that serves as a proxy between the vSphere Client and the vCenter Server. It monitors the network communication between them and translates it into an executable PowerShell code. Later, this code can be modified and saved into a reusable function or script.
For vSphere PowerCLI, run the following command:
Connect-VIServer [IP of the machine where Onyx is running] -Protocol http
-Port [listening port] -User [username] -Pass [password]
You can download Project Onyx Alpha from http://blogs.vmware.com/files/onyx_1.5.3607.25516.zip or http://bit.ly/vmwOnyx15.
To learn how it works please see this video from YouTube.com
This PowerShell script adds a host to a Cluster and licenses it.
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer "VC_server_name" -User "Administrator" -Password "password"
add-vmhost "esxhost" -location (get-datacenter -name 'Datacenter' |
get-folder -name 'Folder' | get-cluster -name 'Cluster') -user "root"
-password "password" -force: $true
$targethostMoRef = (get-VMHost $strHost | get-view).MoRef
$si = Get-View ServiceInstance
$LicManRef=$si.Content.LicenseManager
$LicManView=Get-View $LicManRef
$licassman = Get-View $LicManView.LicenseAssignmentManager
$licassman.UpdateAssignedLicense($targethostMoRef.value,”YOUR LIC KEY”,
”vSphere4 Enterprise Plus (1-12 cores per CPU”)
Disconnect-VIServer -Confirm:$false
Download it here.
VMware have released a demo on YouTube that shows a “must have” for PowerShell users who automate and manage vSphere and vCenter through PowerShell.
The project is named “Onyx” and works like a middelware between the vCenter Client and the vCenter Server.
Onyx is unfortunately still in a private beta and therefore not acceble to the Public……..
Read more on rtfm-ed.co.uk.
http://www.rtfm-ed.co.uk/?p=1643
Or read more on the “get-scripting podcast” blog
http://get-scripting.blogspot.com/2009/08/get-scripting-podcast-episode-12-carter.html
Today I had to create a script that creates lists of VMs, for each of the below statements:
Get it here
A fellow member in the Danish Usergroup has created a very simple backup script for ESX and ESXi using PowerShell and VCB.
I like that it’s small and simple.
Keep up the good work….
2 years ago a VMUG user in Denmark created a Ubuntu VM that could graficily could show the develeoment of the amount of VM’s in a Cluster.
Unfurtionally someone stole my labtop and the VM
.
So I had to create a new. And of cause it’s based on PowerShell
.
The webpages shows the following information
Get the source code in the Download section under Vi Toolkit for Windows
Today I had to upgrade all our Jumphost VM’s from 256MB to 512MB of memory (more than 200 VM’s).
There are two ways accomplice this.
1. Do it manually (Very time consuming)
2. Script it with PowerShell
As the lazy person I am I decided that scripting was the way forward.
The script I came up with is as follows:
Connect-VIServer "vi_servername" -User "vi_username" -Password password"
# Select all VM's that have less than 512MB and change the Memory to 512MB
foreach ($vm in Get-VM | Select Name,MemoryMB | Where-Object{$_.MemoryMB -lt "512"}){
Set-VM $vm.Name -MemoryMB "512" -Confirm:$FALSE
}
To suppress the script to prompt for acceptance each time I added the following option
-Confirm:$FALSE
The script easily be changed to add or update other VM hardware settings.
- Number of CPU’s (Set-VM <vm-name> -NumCpu 2)
- Rename VM (Set-VM <vm-name> -Name “NewName”)
Find more options and ideas in the “Automating VMware with PowerShell – Hands-On Lab” from VMworls 2008.
Just remember if a VM is running you have to poweroff or shutdown the VM before the changes will take effect.
This is because a restart or reset does’t reload the vmx file.
Update:
The script is now updates so it also implements the following settings
Take a look at the scripts here.
I have created at PowerShell script that obtains a list of VM’s that have snapshots attached. The output is then converted to a html file using the cmdlet ConvertTo-HTML.
And just to make it easier to obtain the html file, the script mails the html file to me as an attachment.
Ths script has been updated thanks to Ryan, to be able to handle multiable snapshots on each VM.

Get the script from the Downlaod section.
The past few days I have been trying to learn the basic of PowerShell and the VIToolkit for Windows.
And after playing around with it, I thought that the best way to learn PowerShell was to have a goal.
And what better goal than converting the vcinfo script I created with VIPerlToolkit.
A beta version of the script is now avaiable for download – get it here.
But I have to warn you – the script is still in beta.
I have added a few of the old information and some new ones.
More info will be added when I get the time.
If you have any suggestions on what info the script should show in VC, please let me know.
I was surfing around for new powershell scripts and came across an application for icomasoft that gives you the abbility to add and run your own PS scripts from Virtual Center.
Thyis is just too cool.
Check it out.