Using DHCP reservations and you don’t want to have to use the MMC or remote into the server to make those or see what you have reserved? A quick bit of powershell to make and get those reservations at that exclusive table for you, with a nice little glass of CSV with it!
# A couple of commands to create and get reservations from a remote DHCP server. This requires Powershell Remoting, firewall to open to server, admin rights to server, DhcpServer PS module, and used in ISE 5.1.
# DHCP Remote reservation
$sb = {
$scopeID = "IPsubnet"
$clientMac = "clientmacaddress"
$clientName = "clientcomputername"
$clientIP = "reserveIPaddress"
Add-DhcpServerv4Reservation -ScopeId $scopeID -Name $clientName -IPAddress $clientIP -ClientId $clientMac
}
$dhcpServer = "dhcpservername.fqdn"
Invoke-Command -ComputerName $dhcpServer -ScriptBlock $sb
# Get Remote Reservations
$report =@()
$sb = {
$scopeID = "IPsubnet"
$output = Get-DhcpServerv4Reservation -ScopeId $scopeID | Select-Object Name, IPAddress, ClientID
$report += $output
}
$dhcpServer = "dhcpservername.fqdn"
Invoke-Command -ComputerName $dhcpServer -ScriptBlock $sb
$report | export-csv c:\scripts\logs\dhcpreservations.csv -Append -NoTypeInformation
So you want to upgrade some VDAs?! Yeah you do! I’ve done some edits on other scripts. I’m also working out for additional revisions to check for present sessions. This targets the Server VDA version. You can edit the name to VDAWorkstationSetup_1912.exe in the script and accompanying files to upgrade on VDI as well. The base for this is listed below in the script from ChayScripts. You can also change the install switches and copy that into the install.bat file if you need different options (https://www.citrix.com/blogs/2018/01/08/citrix-vda-commandline-helper-tool/)
For the contents of the ServerNameTextFile, you will need FQDN of the servers for the invoke commands. This splits the FQDN off for the powercli aspect to snapshot the server.
# Base VDA removal / reinstall script. This uses Powershell ISE on 5.1 with needing to be ran with account with rights in VMware and on the target server as well as the module for PowerCLI.
# Modified from https://github.com/ChayScripts/Citrix-VDA-Upgrade-Scripts scripts. Added snapshot for VMware and a report of previous versions.
$vdalist = get-content "C:\pathtotextfilewithfqdnservernames.txt"
$source = "placewherefilesarestored\vdaupgrade"
$dest = "c$\software\vdaupgrade"
$date = Get-Date -Format MMddyyyy
$report = @()
foreach ($vda in $vdalist) {
$line = "" | Select Name, PreviousVersion, SnapShot
$vda1 = ($vda.split('.')[0])
$line.Name = "$vda"
$line.PreviousVersion = (invoke-command -ComputerName $vda -ScriptBlock {Get-WmiObject -Class Win32_Product | where name -match "Citrix Virtual Desktop Agent - x64" | select Name,Version}).Version
$snapshot = (get-vm $vda1 | new-snapshot -name $date-$vda1-preupgrade)
$line.SnapShot = (get-vm $vda1 | get-snapshot).name
Write-Host "Working on $vda"
if (!(Test-Path -Path \\$vda\c$\software\vdaupgrade)) {
New-Item -ItemType Directory -Path \\$vda\c$\software -Name vdaupgrade
Copy-Item "\\$source\install.bat" -Destination \\$vda\$dest -Force
Copy-Item "\\$source\remove.bat" -Destination \\$vda\$dest -Force
Copy-Item "\\$source\VDAServerSetup_1912.exe" -Destination \\$vda\$dest -Force
}
else {
Copy-Item "\\$source\install.bat" -Destination \\$vda\$dest -Force
Copy-Item "\\$source\remove.bat" -Destination \\$vda\$dest -Force
Copy-Item "\\$source\VDAServerSetup_1912.exe" -Destination \\$vda\$dest -Force
}
Invoke-Command -ComputerName $vda -Scriptblock {
$time = (Get-Date).AddMinutes(3)
$action = New-ScheduledTaskAction -Execute 'c:\software\vdaupgrade\remove.bat'
$trigger = New-ScheduledTaskTrigger -Once -At $time
$principal = New-ScheduledTaskPrincipal -RunLevel Highest -UserID "NT AUTHORITY\SYSTEM" -LogonType S4U
Register-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -TaskName "VDAUninstall" -Description "Citrix VDA Uninstall"
}
Invoke-Command -ComputerName $vda -Scriptblock {
$action = New-ScheduledTaskAction -Execute 'c:\software\vdaupgrade\install.bat'
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -RunLevel Highest -UserID "NT AUTHORITY\SYSTEM" -LogonType S4U
Register-ScheduledTask -Action $action -Trigger $trigger -Principal $principal -TaskName "VDAInstall" -Description "Citrix VDA Install"
}
$report += $line
}
$report | export-csv c:\scripts\logs\$date-vda-upgrades.csv -Append -NoTypeInformation
You will need to create an install.bat and remove.bat file with the contents below.
Install.bat
REM change port number in below command.
REM Use citrix vda command line helper tool from citrix. https://support.citrix.com/article/CTX234824 if needed
REM Install new VDA agent, delete files and scheduled tasks. Finally reboot.
C:\software\vdaupgrade\VDAServerSetup_1912.exe /masterpvsimage /virtualmachine /components VDA /controllers "DDC1 DDC2 DDC3" /noreboot /quiet /disableexperiencemetrics /enable_hdx_ports /enable_hdx_udp_ports /enable_real_time_transport /enable_remote_assistance
C:\Windows\system32\schtasks.exe /delete /tn VDAInstall /f
C:\Windows\system32\schtasks.exe /delete /tn VDAUninstall /f
del c:\software\vdaupgrade\remove.bat /F
del c:\software\vdaupgrade\VDAServerSetup_1912.exe /F
C:\Windows\System32\timeout.exe /t 5
C:\Windows\System32\shutdown.exe /r /t 20 /f
del c:\software\vdaupgrade\install.bat /F
This script allows you to get the list of Delivery Groups by “SessionSupport” type and reports back “MultiSession” as “CitrixApp” and SingleSession as “VDI.”
# Script to get MultiSession and SingleSession counts from Delivery Groups with a non-zero user count. This sorts by MultiSession, then SingleSession. This was ran on a machine with Citrix Studio SDK
# installed. This was tested with CVAD 1912 LTSR.
asnp Citrix*
$adminAddress = "deliverycontroller.fqdn"
$getDG = Get-BrokerDesktopGroup -AdminAddress $adminAddress -MaxRecordCount 100000 | Select-Object Name, SessionSupport | Get-Unique -AsString
$report = @()
foreach($dg in $getDG) {
$line = "" | Select DeliveryGroupName, UserCount, SessionSupport
$userCount = (Get-BrokerSession -AdminAddress $adminAddress -DesktopGroupName $dg.name -MaxRecordCount 100000 | Select-Object BrokeringUserName).count
if ($userCount -ne '0' -and $userCount -ne $null){
$line.DeliveryGroupName = $dg.name
$line.UserCount = $userCount
if($dg.SessionSupport -eq "SingleSession") {
$line.SessionSupport = 'VDI'
}
else{
$line.SessionSupport = 'CitrixApp'
}
$report += $line
}
}
$citrixAppTotal = (($report | Where-Object SessionSupport -eq "CitrixApp"| Select-Object UserCount).UserCount| Measure-Object -Sum).Sum
$citrixVDITotal = (($report | Where-Object SessionSupport -eq "VDI"| Select-Object UserCount).UserCount| Measure-Object -Sum).Sum
$appTotal = write-output "`r`nTotal Citrix App users: $citrixAppTotal"
$vdiTotal = write-output "Total VDI Users: $citrixVDITotal"
$report += $apptotal
$report += $vdiTotal
$report | sort SessionSupport, @{Expression="UserCount";Descending=$true}|Format-Table
So you like your reports fresh off the press!? We do too! A quick little script to grab a daily report, running as a scheduled task, and send out some user information. Just in case someone likes to know how many people using the platform.
Gets you this nice little emailed report:
# Get Citrix Daily Users reporting. This requires Powershell, Studio SDK, access rights to the license server.
# This gets the unique users, current sessions, connected and disconnected VDI, and license counts.
# This was tested with 11.17.2.0 build 37000 License Server with 1 license file. Running this as a scheduled task you will need an AD account
# to run this under. A service account works well for this.
asnp Citrix*
$adminAddress = "deliverycontroller.fqdn:80"
$licenseServerAddress = "https://licenseserveraddress:8083"
$licenseServerName = "licenseserver.fqdn"
$cert = Get-LicCertificate -AdminAddress $licenseServerAddress
# This section was gotten from https://lalmohan.co.nz/2015/10/09/citrix-license-usage-monitoring-using-powershell/ and modified for my use.
$licenseInfo = Get-WmiObject -Namespace "ROOT\CitrixLicensing" Citrix_GT_License_Pool -ComputerName $licenseServerName
$licenseModel = ($LicenseInfo | Where-Object{($_.pld -like "XDT*") -or ($_.pld -like "MPS*")}|Select-Object pld -unique).pld
$totalLicenses = ($licenseInfo | Where-Object PLD -like "$licenseModel" | Select-Object count).count
# End section.
# This section was assisted from http://notesofascripter.com and https://www.linkedin.com/in/douglas-ruehrwein-56835869/
# This will run differently for Monday since you are getting data from the last 24 hours and weekends are usually lower use.
$Today = Get-Date
if(($Today.DayOfWeek) -eq 'Monday')
{$when = $Today.AddDays(-3)}
else{$when = $Today.AddDays(-1)}
# End section.
$connections = Get-BrokerConnectionLog -AdminAddress $adminAddress -Filter {BrokeringTime -gt $when} -MaxRecordCount 100000 | Select-Object BrokeringUserName
$licenseCount = (Get-LicUsageDetails -AdminAddress $licenseServerAddress -ProductEditionModel $licenseModel -CertHash $cert.CertHash).count
$ctxUsers = [PSCustomObject] @{
UniqueCitrixUsers = ($connections.BrokeringUserName | Select-Object -Unique).count
CurrentSessions = (Get-BrokerSession -AdminAddress $adminAddress -MaxRecordCount 100000 | Select-Object BrokeringUserName).count
CitrixVDIConnected = (Get-BrokerSession -AdminAddress $adminAddress -MaxRecordCount 100000 | Where-Object SessionSupport -eq "SingleSession" | Where-Object SessionState -eq "Active").count
CitrixVDIDisconnected = (Get-BrokerSession -AdminAddress $adminAddress -MaxRecordCount 100000 | Where-Object SessionSupport -eq "SingleSession" | Where-Object SessionState -eq "Disconnected").count
CitrixLicensesUsed = $licenseCount
CitrixTotalLicenses = $totalLicenses
CtxLicenseFreePercent = ((($totalLicenses - $licenseCount) / $totalLicenses ) * 100).ToString("#.##")
}
# HTML Formatting
$style = "<style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "</style>"
# HTML Email Body
$body = $ctxUsers | ConvertTo-Html -Head $style
# Generates email with attachment
$date = Get-date -Format "MM-dd-yyyy"
$emailFrom = "someemail@place.com"
$emailto = "someemail@place.com"
#$emailtwo = "someemail@place.com"
#$emailCC = "someemail@place.com"
$subject="Daily Citrix User Report | $date"
$email = New-object System.Net.Mail.MailMessage
$email.to.Add($emailto)
#$email.to.Add($emailtwo)
#$email.CC.Add($emailCC)
$Email.From = New-Object system.net.Mail.MailAddress $emailFrom
$email.Subject = $subject
$email.IsBodyHtml = $true
#$attachment = $Reports[1]
#$email.Attachments.add($attachment)
$email.body = $body
$smtpserver="stmp.someplace.com"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($email)
So you run SiteManager. And somebody done decided they want to make a new server that will host the security.dat file. And… You already did the work to create custom .ini file locations for the users. NOW you have to change all those smapp.ini files with the updated location of the security.dat file. How dare they?! Well. That could be some fun if you have a lot of users. Wait…. Powershell for the rescue! If you happen to use a profile server to host the user files, you can easily replace it with the new location of the security.dat file.
Update: Not sure what happened, but the code paste didn’t take evidently. I blame gremlins. It has been corrected.
# Replace a line / value in .ini file stored in Citrix UPM folder location when a change to the application is made.
# An example is for SiteManager, if you change the location of the .dat file for security.dat file and you are using a custom .ini
# created and stored with the user profile.
$filePath = "e:\locationofupmfolders"
$Files = Get-ChildItem -Path $filePath -Recurse -File -force -Include "smapp.ini"
foreach($file in $files)
{
$find = "value-you-want-to-change"
$replace = "value-you-want-to-change-to"
$content = Get-Content $($file.FullName) -Raw
#write replaced content back to the file
$content -replace $find,$replace | Out-File $($file.FullName) | write-output
}
Easy peasy. Now they have the new location of the security.dat file!
Wouldn’t you know it!? A vCenter certificate got changed out and now your hypervisor connector is showing it no worky. Come to find out you missed the email memo that the certificate was getting changed. Or you might’ve been busy and didn’t think too much of it. Well, now you have to get it fixed! What if there was a way to get that information quickly and easily so that you just had to do some copy / paste magic to resolve it? Well…. There is! This handy dandy little script will get those pesky thumbprints and kick them out as a csv so you can use them to update your connector in the XenDesktop database.
# A script to check SSL thumbprints on your Citrix hypervisor connections. This will get all of the thumbprints of your connectors and will get the SSL thumbprints of your vCenters if you happen to have more than one.
# This is for running on in-premise Citrix farm (7.x) on a Delivery Controller with 10.1.0 VMware.PowerCLI module and the Citrix SDK installed with VMware ESXi 7.0U1 or later. This also is ran in ISE. Get-SSLThumbprint function is from https://gist.github.com/lamw/988e4599c0f88d9fc25c9f2af8b72c92
# with the return $SSL_THUMBPRINT -replace '(..(?!$))','$1' changed from ending in '$1:' The instructions for changing the SSL thumbprint can be found at https://support.citrix.com/article/CTX224551.
asnp Citrix*
Function Get-SSLThumbprint {
param(
[Parameter(
Position=0,
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)
]
[Alias('FullName')]
[String]$URL
)
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class IDontCarePolicy : ICertificatePolicy {
public IDontCarePolicy() {}
public bool CheckValidationResult(
ServicePoint sPoint, X509Certificate cert,
WebRequest wRequest, int certProb) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy
# Need to connect using simple GET operation for this to work
Invoke-RestMethod -Uri $URL -Method Get | Out-Null
$ENDPOINT_REQUEST = [System.Net.Webrequest]::Create("$URL")
$SSL_THUMBPRINT = $ENDPOINT_REQUEST.ServicePoint.Certificate.GetCertHashString()
return $SSL_THUMBPRINT -replace '(..(?!$))','$1'
}
$xdConnections = Get-ChildItem XDHyp:\Connections | Select HypervisorConnectionName, HypervisorAddress, SslThumbprints
$xdThumbprints = @()
foreach($xdc in $xdConnections)
{
$line = ""| Select HypervisorConnectionName, HypervisorAddress, SslThumbprints, vCenterThumbprints, SameThumbprint
$line.HypervisorConnectionName = ($xdc).HypervisorConnectionName
$line.HypervisorAddress = ($xdc).HypervisorAddress | Out-String
$line.SslThumbprints = ($xdc).SslThumbprints | Out-String
$line.vCenterThumbprints = Get-SSLThumbprint (($xdc).HypervisorAddress | Out-String)
$line.SameThumbprint = ($line.SslThumbprints -match $line.vCenterThumbprints)
$xdThumbprints += $line
}
$xdThumbprints | Export-Csv c:\scripts\logs\sslthumbprints.csv
You ever get an email from a user that just has their name in it and my VDI isn’t working? You ever go to Citrix Studio and look for the user and sort to find them? Well…. How about a better, faster, more streamlined way!? (Might be some powershell involved)
Look no further! Below is a fast and easy way to find that machine that the user just may have happened to forget to include in said email!
If you happen to do the above, you get this:
And so you can do that sweet, sweet copy / paste, code snippet below.
I’m sure many of you out there like ArcGIS and all that it can do for you! Well, maybe you have it in Citrix. Maybe you have custom SearchOptions.cfg’s. Maybe you have style sheets. Maybe you even like to have viewer and professional license versions available to all your users. Well….. In the long long ago, batch was the thing to power all things like this. What if. Just what if I told you, that powershell works too!? How awesome would that be?! You can upgrade your script from batch and stroll down PoSH street! How about see below and you too, for the low low price of free, can enjoy this method too!
**Fixed an issue with the ESRI_SOFTWARE_CLASS not respecting the Viewer / Professional option. This was tested and the issue is corrected.Change has been made below.** **Made an edit to reduce the number of changes you have to make and make it easier to switch between ArcGIS Desktop versions.**
# This is to launch ESRI ArcGIS in Citrix. This is using PowerShell version 5.1.17763.1971, on Server 2019 hosts, with Citrix UPM, and with ArcGIS 10.8.1 and with Seach Options. You can comment out
# the Search Options if you are not using them.
# Date: 08182021
# This sets the $username variable which will be used to map drives.
$UserName = [Environment]::UserName
# Sets profile server name for Citrix UPM. Enter profile server FQDN.
$profsrv = "profileservername.fqdn"
# Sets ArcGIS Version to be used in the script. There are several references to the version in the script. Enter version in format below.
$arcver = "Desktop10.8"
# Sets license server location. Enter license server FQDN.
$licsrv = "licenserver.fqdn"
# This section is to set the locations for _master if hosting on profile server (You can use whereever the _master location is as long as permissions are set and it is accessible
# from the network the Citrix hosting VDA's are located.You can use other drive letters, just make the change to the variables below and the section on removing drives and remapping.# This is location of "SearchOptions.cfg" files.
# This is location of "SearchOptions.cfg" files.
$Master= "\\$profsrv\GIS\_master"
# Location of ArcCatalog.gx, GxDBFactCache.dat, and GxObjFactCache.dat files.
$Desk= "\\$profsrv\GIS\_desk"
# Location of ArcMap Toolbox and styles.
$Desk1= "\\$profsrv\GIS\_desk1"
# Location of drives for GISDATA.
$QDest = "\\$licsrv\GISDATADRIVE"
$SDest = "\\$licsrv\GISDATADRIVE"
$NDest = "\\nas.fqdn\dfs\sharename"
# This tests to see if the location for the Search Options have previously been created for the user, and creating them if it is not present.
If (!(Test-Path "\\$profsrv\CITRIXUPM\$UserName\UPM_Profile\AppData\Local\ESRI\$arcver\ArcCatalog\SearchIndex\Configs\searchoptions.cfg")) {
Write-Host "Please wait while your Search Options are created..."
robocopy $Master "C:\Users\$UserName\AppData\Local\ESRI\$arcver\ArcCatalog\SearchIndex\Configs" /e /S
}
# This tests to see if the ArcCatalog options have previously been created, and create them if not.
If (!(Test-Path "\\$profsrv\CITRIXUPM\$UserName\UPM_Profile\AppData\Local\ESRI\$arcver\")){
Write-Host "Please wait while your ArcCatalog Options are created..."
robocopy $Desk "C:\Users\$UserName\AppData\Roaming\ESRI\$arcver\ArcCatalog\" /e /S /Y
}
# This tests to see if the ArcCatalog options have previously been created, and create them if not.
If (!(Test-Path "\\$profsrv\CITRIXUPM\$UserName\UPM_Profile\AppData\Local\ESRI\$arcver\")){
Write-Host "Please wait while your ArcCatalog Options are created..."
robocopy $Desk1 "C:\Users\$UserName\AppData\Roaming\ESRI\$arcver\" /e /S /Y
}
# This removes any mapped drives that might previously have been mapped.
Remove-PSDrive Q,S,N –Force -Verbose
# This maps the drives to the locations for ArcGIS data and files.
New-PSDrive -Name Q -PSProvider FileSystem –Root "$QDest"
New-PSDrive -Name S -PSProvider FileSystem –Root "$SDest"
New-PSDrive -Name N -PSProvider FileSystem –Root "$NDest"
# Sets the Class version to "Professional" license use. Comment out the Professional and uncomment the Viewer to change version.
set ESRI_SOFTWARE_CLASS="Professional"
#set ESRI_SOFTWARE_CLASS="Viewer"
# This sets the location of the executable for the ArcGIS files and starts the process.
$dir = "C:\Program Files (x86)\ArcGis\$arcver\bin"
Start-Process $dir\ArcMap.exe
Now this above will get the script for you. But… You have to publish it as well! So, how about them settings!? This is the screenshot of the settings to use to publish it. You will need to go back and change the icon if you want to have it show the ArcGIS icon instead of the powershell icon. For the copy / pasters out there:
Publishing Citrix app settings:
Path to the executable file: C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
Command line arguments: -ExecutionPolicy Bypass c:\appscripts\ArcMapAdv-PS.ps1
Working directory: C:\WINDOWS\system32\WindowsPowerShell\v1.0\
So there you have it! A way to launch ArcGIS in Citrix with powershell instead of batch!
Have you ever had machines not reboot properly? Have you had VMs you just don’t know if are awake and ready to serve your hungry customers? Have you ever just wanted to know if they are stepping through their paces? Well, here at XenApplePie, we have a solution for you! For only 35 payments of $0.00, you too can own this piece of automated automation!
But seriously. Sometimes you have a reboot policy set on your Delivery Group, and for some reason that pesky VM just doesn’t want to turn back on (From checking what it does, it looks like the DDC sends a shutdown and then a start command to reboot it). If you have had this happen, it can be frustrating to come in and either your hosting machine is off and users can’t access, or you can have a machine turned up to 11 to support your users. This little script, ran daily, can help prevent such frustrations and symptoms such as: pounding head on desk; shouting to the skies about your fury; verbal diarrhea of expletives not suitable for aural consumption.
Update below to the trim method used. The new method uses the split method versus the substring method. This method will work better as the length of the domain name won’t affect the outcome of the scripts and will save from making edits to the script for each domain.Another edit is for the HTML formatting to make it more readable in the report that is emailed.
So without further ado, well, ado ado ado. Here you go!
# This script was tested with 1912LTSRCU1 using Powershell 5.1.17763.1852 with PowerCLI version VMware PowerCLI 12.2.0 build 17538434 on vSphere 7.x.
# Build Date: 06292021
# https://www.pdq.com/blog/secure-password-with-powershell-encrypting-credentials-part-2/
# The above link contains the method to encrypting the password to use for the script and schedule in task scheduler.
# Loads Citrix snapins (This is assuming you have loaded the Citrix SDK / Studio on the machine that will run the check.)
Add-PSSnapin Citrix*
# vCenter connection section
# This tells PowerCLI to ignore invalid certicate action.
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -DisplayDeprecationWarnings $false -Scope Session -Confirm:$false
# This section is done via the method above in the pdq article for doing powershell scripts with encryption to show how to make the cred file, key file, and encrypt the information.
# The section also from https://notesofascripter.com
$password = Get-Content C:\scripts\creds.txt | ConvertTo-SecureString -Key (Get-Content C:\scripts\creds.key)
$credentials = New-Object System.Management.Automation.PsCredential("domain\username",$password)
Connect-VIServer somevcenteraddress -Credential $credentials
# End https://notesofascripter.com
# This is to get the list of machines from the delivery controller with the filter to get a specific set of machines.
$machines = Get-BrokerMachine -AdminAddress "delivery-controller.domainfqdn:80" -Filter {CatalogName -contains '*some_catalog_name_string*'}|Select-Object -Property machinename, desktopgroupname,inmaintenancemode
# This sets up an array to manipulate
$machine_array = @($machines)
# This goes through the array and removes VMs that have the "inmaintenancemode" value set as "True."
$machines_avail = $machine_array |where-object {$_.inmaintenancemode -ne "true"}
# The output of the Get-Brokermachine will retrieve the "machinename" with the domain preface. This trims the preface domain\servername. This method is better than the previously listed method as it will split at the "\" character, regardless of the length of the domain preface.
$vmtrim = $machine_avail.machinename
$vmtrimmed = (($vmtrim)|%{ ($_ -split '\\')[1]})
# This takes the result of the value above and assigns it to another variable that will be used to power on machines that have powered off.
$vmnames = $vmtrimmed
# This gets the additonal information from the "Get-VM" command and places it in a variable.
$vm = Get-VM $vmnames
# This creates and assigns the output of the "foreach if / else" loop.
# This section was utilized from site "https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/PowerCLI-start-multiple-VM-if-poweredOff/td-p/501598."
$output = $vm | foreach {
# This checks to see the value of the "PowerState" being "PoweredOff."
if ($_.PowerState -eq "PoweredOff") {
# This shows a message that a VM was started and generates an output for your report.
"Starting $($_.name) on $($_.VMHost)"
# This starts the VM and captures the output for the report.
$StartingVMs = Start-VM $_ -Confirm:$false
}
else {
# This generates a message for the output for the report if the VM is already running.
"$($_.name) is already running on $($_.VMHost)"
}
}
# HTML Formatting
$style = "<style>BODY{font-family: Arial; font-size: 10pt;}"
$style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}"
$style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }"
$style = $style + "TD{border: 1px solid black; padding: 5px; }"
$style = $style + "</style>"
# HTML Email Body
$body = $report | ConvertTo-Html -Head $style
# End of section from "https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/PowerCLI-start-multiple-VM-if-poweredOff/td-p/501598."
# Generates email with attachment.
# This section to end was gotten from assistance from the author of https://notesofascripter.com. This also uses the .NET method of generating the email.
# Notesofascripter section
$date = Get-Date -Format "MM-dd-yyyy"
$emailFrom = "yourserviceemail@company.com"
$emailto = "youremailgroup@company.com"
$subject = "Daily Something Server Check| $date"
$email = New-object System.Net.Mail.MailMessage
$email.to.Add($emailto)
$emailCC = "emailgroup@company.com"
#$email.CC.Add($emailCC)
$Email.From = New-Object system.net.Mail.MailAddress $emailFrom
$email.Subject = $subject
$email.IsBodyHtml = $true
#$attachment = $Reports[1]
#$email.Attachments.add($attachment) If you want to do as attachment
$email.body = $body
$smtpserver="smtp.company.com"
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($email)
;
# End of Notesofascripter section.
# Disconnect from vcenter
Disconnect-VIServer * -confirm:$false