Virtualization, technology, and random rantings with a focus on Citrix and VMware.

Category: PowerCLI

Getting Network Names Of VDI Machines

Sometimes it is just good to have all the network names of your VDI and IP. This will get the VM name, network adapter, network name defined in vSphere, and IP.

# Script to get network names for VDI machines. This was tested with VMware 7.x, Citrix Cloud connection configured with the "default" profile, and VDI with single NIC.

asnp Citrix*
Get-XDAuthentication -ProfileName "default"

$date            = Get-Date -Format MMddyyyy
$report          = @()
$CurrentItem     = 0
$PercentComplete = 0
$ctxVDI          = (Get-BrokerMachine -MaxRecordCount 100000 | Where-Object SessionSupport -eq "SingleSession" | Where-Object HostedMachineName -ne $null | Select-Object HostedMachineName).HostedMachineName
$totalItems      = ($ctxVDI).count

foreach($ctx in $ctxVDI){
  Write-Progress -Activity "Getting network name for $ctx" -Status "$PercentComplete% Complete:" -PercentComplete $PercentComplete
  $line             = "" | Select-Object VM, Name, NetworkName, IPAddress
  $networkInfo      = (Get-VM $ctx | Get-NetworkAdapter)
  $ipAddress        = (Get-VM $ctx | Select-Object @{N="IPAddress";E={@($_.guest.IPAddress[0])}})
  if($networkInfo -ne $null){
    $line.VM          = $ctx
    $line.Name        = $networkInfo.Name
    $line.NetworkName = $networkInfo.NetworkName
    $line.IPAddress   = ($ipAddress).IPAddress
  $report += $line
  $PercentComplete = [int](($CurrentItem / $TotalItems) * 100)

$report | export-csv c:\scripts\logs\$date-vdinetworks.csv -NoTypeInformation -Append

Sample Output

VDA Upgrade… Oh Yeah!

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 (

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 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.

REM change port number in below command.
REM Use citrix vda command line helper tool from citrix. 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

"C:\Program Files\Citrix\XenDesktopVdaSetup\XenDesktopVdaSetup.exe" /REMOVEALL /QUIET /NOREBOOT
C:\Windows\System32\shutdown.exe /r /t 5 /f

Under My SSL Thumbprint

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
# with the return $SSL_THUMBPRINT -replace '(..(?!$))','$1' changed from ending in '$1:' The instructions for changing the SSL thumbprint can be found at 

asnp Citrix*

Function Get-SSLThumbprint {

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

Is That VM Running Or Taking A Nap?

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
# 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
$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

# 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 ""
$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 $($ 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.
        "$($ 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 ""

# Generates email with attachment.
# This section to end was gotten from assistance from the author of This also uses the .NET method of generating the email.
# Notesofascripter section
$date = Get-Date -Format "MM-dd-yyyy"
$emailFrom = ""
$emailto = ""
$subject = "Daily Something Server Check| $date" 
$email = New-object System.Net.Mail.MailMessage 
$emailCC = ""
$Email.From = New-Object $emailFrom
$email.Subject = $subject
$email.IsBodyHtml = $true
#$attachment = $Reports[1]
#$email.Attachments.add($attachment) If you want to do as attachment
$email.body = $body

$smtp = new-object Net.Mail.SmtpClient($smtpServer)
# End of Notesofascripter section.

# Disconnect from vcenter
Disconnect-VIServer * -confirm:$false

PoSh Spice Be Here!

I want to take a moment… Ok, that moment’s over. Bringing to you from the world of powershell, powercli, and power scripting….. Stuart Yerdon, and the webmaster of He has been featured as a vExpert, a connoisseur of all things M:TG (If you have to ask….), and a colleague and friend of mine. Check out his site and all things powershell. If you got a problem, and you can find him (you can at, you’ll find what you seek.

Powered by WordPress & Theme by Anders Norén