Jump to content
Updated Privacy Statement
  • 6

Powershell Script repository.


Randy White1709153608

Question

I've looked for a script repository on here or a common place that people post scripts they have created and I havent had much luck. So I thought I would start a thread and see where it goes from there. Use the scripts in this thread with caution and ask questions if your not familiar with Powershell.

 

Also I should have mentioned that if you see something wrong with any of these scripts or maybe a better way of doing something please feel free to give suggestions. 

  • Like 4
Link to comment
  • Answers 58
  • Created
  • Last Reply

Top Posters For This Question

Recommended Posts

  • 0
On 6/20/2017 at 5:47 AM, Randy White1709153608 said:

Function to reset users session

 

Loads Powershell snapins

Script is for killing sessions from PS prompt. I'm in the process creating a tool that calls this function. 

 

msiexec /i "unc_path\Powershell_Snapins\Broker_PowerShellSnapIn_x64.msi" /quiet
asnp citrix*
$ddc = "controller"
 
function reset-user{
[cmdletbinding()]
param (
        [Parameter(Mandatory=$true)]
        [string]$User
    )
        Invoke-command -Computer $ddc -scriptblock {param([string]$LocalUser) ; Add-PSSnapin Citrix* ; Get-BrokerSession -max 10000 | Where-Object brokeringusername -eq  "$env:USERDOMAIN\$($LocalUser)"| Stop-BrokerSession } -ArgumentList $user
}
 

Example

reset-user username

Hi Randy, Do we have a similar kind of script which also provides an option for killing the specific application inside an ICA session.

Link to comment
  • 0

I wrote this for my colleagues to check performance on any deliverygoup on our sites.

 

the output:

Servers          : 149
Sessions         : 760
Average Sessions : 5
Average Load     : 1,458
Average CPU      : 938
Average Memory   : 1,037
Top Load         : 3382 server1127
Top CPU          : 3329 server1127
Top Memory       : 1958 server1127

 

Add-PSSnapin Citrix.* -erroraction silentlycontinue

write-host "============== Sites =============="
write-host ""
write-host "1   SEU(Europe)"
write-host "2   SLA(South America)"
write-host "3   SSEA(Asia)"
write-host ""
$isite = read-host "Choose site(Default 1)"
switch($isite)
{
    "1" {$site = "seucontroller.example.com";break}   
    "2" {$site = "slacontroller.example.com";break}
    "3" {$site = "sseacontroller.example.com";break}
    default {$site = "defaultsitecontroller.example.com";break}
}

write-host ""

$groups = (get-brokerdesktopgroup -AdminAddress $site).Name
$i = 1
$menuitems = @{}

foreach ($group in $groups)
{
 $menuitems.Add($i,$group)
 $i++   
}

write-host "============== Delivery Groups =============="

$menuitems.GetEnumerator() |Sort-Object -Property name |Format-Table -AutoSize -HideTableHeaders 

$apa = $null
$apa = read-host "Choose a number"
if(!($apa)){
    write-host "No Delivery group choosen"
    exit
    }

$asd = $menuitems.item([INT]$apa)

$servers = Get-BrokerMachine -AdminAddress $site -DesktopGroupName $asd -InMaintenanceMode $false -Property "dnsname","sessioncount","loadindex","loadindexes"
$totLoadIndex = 0
$totSessions = 0
$totCPU = 0
$totMEM = 0
$servCount = $servers.Count
$topCPU = ""
$tmpCPU = 0
$topMEM = ""
$tmpMEM = 0
$topLoad = ""
$tmpLoad = 0
foreach($server in $servers)
{
    $totLoadIndex= $totLoadIndex + $server.LoadIndex
    $totSessions = $totSessions + $server.SessionCount
    $servername = ($server.DNSName.Split("."))[0]
    if($server.LoadIndex -gt $tmpLoad)
    {
        $tmpLoad = $server.LoadIndex
        $topLoad = [STRING]$tmpLoad + " $servername"
    }
    $i = 0
    foreach($li in $server.LoadIndexes)
    {
        $tmp = $li.split(":")
        
        if($tmp[0] -eq "CPU")
        {
            $totCPU = $totCPU + [INT]$tmp[1]
            if([INT]$tmp[1] -gt $tmpCPU)
            {
                $tmpCPU = $tmp[1]
                $topCPU = $tmpCPU + " $servername"
            }
        
        }elseif($tmp[0] -eq "Memory")
        {
            $totMEM = $totMEM + $tmp[1]
            if([INT]$tmp[1] -gt $tmpMEM)
            {
                $tmpMEM = $tmp[1]
                $topMEM = $tmpMEM + " $servername"
                
            }
        }
    }
}

$averageLoad = $totLoadIndex / $servCount
$averageSessions = $totSessions / $servCount
$averageCPU = $totCPU / $servCount
$averageMEM = $totMEM / $servCount

$obj = [PSCustomObject]@{
    "Servers" = $servCount
    "Sessions" = $totSessions
    "Average Sessions" = ("{0:N0}" -f $averageSessions)
    "Average Load" = ("{0:N0}" -f $averageLoad)
    "Average CPU" = ("{0:N0}" -f $averageCPU)
    "Average Memory" = ("{0:N0}" -f $averageMEM)
    "Top Load" = $topLoad
    "Top CPU" = $topCPU
    "Top Memory" = $topMEM
}
$obj 
#$body = ConvertTo-Html -InputObject $obj | out-string 
#Send-MailMessage -to "email1@example.com","email2.example.com" -from "donotreply@example.com" -SmtpServer mailhost.example.com -Subject "Performance Report" -Body $body -BodyAsHtml

#"$servcount, $averageSessions, $averageLoad, $averagecpu, $averageMEM" >> perf.csv

 

Link to comment
  • 0

I've been tasked with cleaning up our AD groups assigned to Citrix apps and giving description to those AD groups so as to know what group gives access to what app as sadly its not always clear. I have XD 7.6LTSR and I have been using the below script which I've modified from its original source. It has been very useful for capturing inventory and pertinent information about the App but I have one issue I would like to see if anyone had a better solution too. I would like to split the user account field so that when I view in excel each account has its own tab so as to be able to organize possible overlapping accounts to applications. In either case, I've found this is a very useful script.

 

add-pssnapin Citrix.* -erroraction silentlycontinue
# Create variables
 
$outpath = ".\XenApp_Published_App_Report.csv" #[environment]::getfolderpath("mydocuments") + "\XenApp_Published_App_Report.csv"
$xaapplist = Get-BrokerApplication -MaxRecordCount 1000 | sort-object Browsername 
$appreport=foreach ($application in $xaapplist) {
     write-host "Current App   "   $application.BrowserName
     Get-BrokerApplication -MaxRecordCount 1000 -BrowserName $application.BrowserName
     write-host "Finished App                                               "   $application.BrowserName
}
 
# pipe appreport variable and select required objects for output
$appreport |
select-object BrowserName,
PublishedName,
ApplicationName,
AdminFolderName,
AdminFolderUid,
ApplicationType,
Enabled,
Visible,
@{n='Accounts'; e={$_.AssociatedUserNames}},
#@{n='servernames'; e={$_.servernames}},
#@{n='workergroupnames'; e={$_.workergroupnames}},
WorkingDirectory,
Commandlineexecutable,
CommandLineArguments,
Clientfolder |
 
#Export results to a CSV
 
export-csv $outpath

 

Link to comment
  • 0

Hi,

 

I don't have access to a Citrix environment. Would someone be able to test this for me?

 

I'm just trying to get the the desktop groups and then workout what users (Either AD groups or direct users) have access.

 

$a = Get-BrokerDesktopGroup | foreach ($Name in $a.Name) {Get-BrokerAccessPolicyRule -DesktopGroupName $Name | select $Name, -expandproperty IncludedUsers} | Export-CSV C:\Xenapp7_BrokerDesktopGroup.csv

 

Many Thanks

 

Link to comment
  • 0
On 5/26/2018 at 5:04 AM, Rhonda Rowland1709152125 said:

 

This will get you closer to what you want (but someone else may be able to tweak it better for you):

$groups = get-brokeraccesspolicyrule 
$groups | select-object @{n='APRName'; e={$_.Name}},DesktopGroupName -ExpandProperty IncludedUsers | export-csv c:\Xenapp7_BrokerDesktopGroup.csv

 

Each BrokerAccessPolicyRule includes the desktopGroupName it is associated with, so you could just pull back the rules to find all desktop groups. If you only want the rules for specific groups, then the command would need updating. Mostly you were using pipes in places where you needed separate commands

Because both the AccessPolicyRule and the Expanced IncludedUsers contain a name field, I renamed the APR name field in the output, but you could exclude it, but I find it helpful to track the multiple access policy rules per delivery group especially if delivering apps and desktops.  And if you only want the group name returned vs. sid/upn, additional work is needed.

 

I may not have time to play anymore with this until next week, so if someone has a better way to do this, feel free to correct.

 

 

 

Thanks Rhonda. I will be able to test this soon. Thinking I might just get a test environment setup. Thanks again.

 

Link to comment
  • 0
On ‎6‎/‎29‎/‎2017 at 6:46 AM, Randy White1709153608 said:

I wanted to know what machines were in maintenance mode in a certain delivery group. 

 

 

$machines = (Get-BrokerMachine -AdminAddress $adminaddress -DesktopGroupName $deliverygroup | Select-Object Hostedmachinename).hostedmachinename
 
foreach($machine in $machines){
 
    $machinelist = Get-BrokerMachine -HostedMachineName $machine
        if($machinelist.InMaintenanceMode -eq $true){
            write-host "$machine is in maintenance mode"
            }else  {
            write-host "$machine is not in maintenance mode"
            }
 
    }

It seemed to be working but I wonder how does the variable $machine gets its value. I don't see any input for $machine only see it for $machineS. Tried the same process for user account and it started throwing error with $user

Link to comment
  • 0
On 6/19/2017 at 8:11 PM, Randy White1709153608 said:

I've looked for a script repository on here or a common place that people post scripts they have created and I havent had much luck. So I thought I would start a thread and see where it goes from there. Use the scripts in this thread with caution and ask questions if your not familiar with Powershell.

 

Also I should have mentioned that if you see something wrong with any of these scripts or maybe a better way of doing something please feel free to give suggestions. 

Hi Everyone - As part of our Citrix Developer Advocacy we continually published a set of tools for developers to get up and running using the Citrix Technology and SDKs. One of those tools that might be of interest to this group/forum is our Citrix Developer Extension for Visual Studio Code. This tool allows you to package up your scripts into a single file and then be able to distribute it for use within the Citrix Developer VSCode extension. We're also looking at additional ways to provide better discoverability to the community to get their scripts noticed.

 

Check out the extension here https://marketplace.visualstudio.com/items?itemName=CitrixDeveloper.citrixdeveloper-vscode  and let me know what you think. There is also a supplemental tool that helps you package up your scripts at https://www.npmjs.com/package/citrix-script-packager

 

Also if you would like to see it in action, check out the video - https://youtu.be/pdt1uFV-kpE

 

Developer Advocate (Citrix)

John McBride

Link to comment
  • 0
On ‎6‎/‎19‎/‎2017 at 8:11 PM, Randy White1709153608 said:

I've looked for a script repository on here or a common place that people post scripts they have created and I havent had much luck. So I thought I would start a thread and see where it goes from there. Use the scripts in this thread with caution and ask questions if your not familiar with Powershell.

 

Also I should have mentioned that if you see something wrong with any of these scripts or maybe a better way of doing something please feel free to give suggestions. 

You should check out the Citrix PowerShell Script Repository on GitHub.  https://github.com/citrix/Powershell-Scripts

Link to comment
  • 0
On 6/20/2017 at 10:46 PM, Randy White1709153608 said:
Restarts computers that are powered on but unregistered. 

 

 

 

 

 

 

 

asnp citrix*

 

 

$bdg = Get-BrokerMachine -AdminAddress "Your_ddc" -MaxRecordCount 100000 | where {$_.PowerState -ne "Off" -and $_.InMaintenanceMode -eq $false -and $_.RegistrationState -eq "UNRegistered"}  | select MachineName,RegistrationState,InMaintenanceMode,Powerstate

 

 

foreach ($Machine in $bdg) 

 

 

{

 

 

        #Restart-Computer $Machine

 

 

        New-BrokerHostingPowerAction -Action 'Reset' -MachineName $Machine.MachineName

 

 

}

 

 

$filedate = (get-date).Month.ToString() + (Get-Date).Day.tostring() + (get-date).Year.tostring()

 

 

$outputfile = "c:\XD_rebooted_" + $filedate + ".csv"

 

 

$bdg | Out-File $outputfile 

 

 

Why not  - check if machine is up, restart desktop service and check if registered. If not then reboot? 

Link to comment
  • 0

Gets unregistered Machines and sends mail to chosen mailbox. I have also excluded some of servers which are used for testing.


 

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

Add-PSSnapin Citrix*

$Date = Get-Date
$To = "user@domain.com"
$From = "XADeliveryControllers@domain.com"
$SMTPSrv = "mailSRV.domain.local"
$Body = Get-Content "C:\PS\XAMachineStat.html" -Raw
$XAServers = '^(XAX2_Main|XAX|XA36-TEST)'
$CountXAMachines = (Get-BrokerMachine -Filter {RegistrationState -eq 'Unregistered'} | ?{$_.HostedMachineName -notmatch $XAServers}).count

try {
    if (-NOT ($CountXAMachines -eq 0)) {
        $BrokerList = Get-BrokerMachine -Filter {RegistrationState -eq 'Unregistered'} | ?{$_.HostedMachineName -notmatch $XAServers} | Select-Object @{n='ComputerName';e={$_.HostedMachineName}},PowerState,@{n='MaintenanceMode';e={$_.InMaintenanceMode}} | ConvertTo-Html -Property ComputerName,PowerState,MaintenanceMode -Head $Header | Out-File C:\PS\XAMachineStat.html -ErrorAction Stop
        Send-MailMessage -to $To -From $From -Subject "XA Servere Status $Date" -Priority High -SmtpServer $SMTPSrv -Body $Body -BodyAsHtml
    }
    else {
        Write-Verbose "No Machine is unregistered. Skipping..."
    }
}
catch {
    $_ | Out-File C:\PS\XAError.html -Append
}

 

Link to comment
  • 0

Turn on, Turn off, or reboot a server on the vSphere level if you use VMWare as your hypervisor. This is handy mainly if the server is off and don't want to log into the vCenter. I mainly use this when updating PVS but has helped in other scenarios, for an example when the server is in a bad state and won't allow a reboot within the OS itself or any new connections.

 

Asnp Citrix*

Import-Module VMware.VimAutomation.Core

 

#Used to recognize admin account 

If($env:USERNAME -like "*t*") {

$strAdmin = "$($env:USERNAME)"

}Else{

$strAdmin = "$($env:USERNAME)t"

}

 

If( ($cred -eq $null) -or ($cred -notlike "*$($env:Username)*") ) {

$cred = Get-Credential "$($ENV:USERDOMAIN)\$($strAdmin)"

}else{

CONTINUE

}

$VerbosePreference = "Continue"

$vcservers = @("vShere.domain.com","vShere.domain.com"))

# Connects to the Vsphere

set-PowerCLIConfiguration -invalidCertificateAction "ignore" -confirm:$false | Out-Null

Connect-VIServer -Server $vcservers -Credential $cred | Out-Null

 

$whattodo = Read-Host "Enter what you want to do. (Start, Stop ((NOTE: This is a Hard stop)), Restart)"

$server = Read-Host "What is the server name?"

switch ($whattodo)

{

'Start' {Start-VM -VM $server -Confirm:$false}

'Stop' {Stop-VM -VM $server -Confirm:$false}

'Restart' {Restart-VM -VM $server -Confirm:$false}

Default {}

}

Link to comment
  • 0

This is something I built, with the help from Michael, Thanks Michael!

I use this to automate our morning report to make sure the environment is working as it should. It has helped many times over. Hope this is useful to someone!

 

It checks for unregistered servers and reboot if needed, make sure Netlogon is up and running, and provides a report in an email to our team. It reports any server names that needed to be corrected so we can go back and check them if needed. Let me know if you have any suggestions that you may be doing in your environment.

 

 

# ***************************************************************************************************

# Created on 12/08/2018

# by Dwayne Dunivan

<#

Purpose:

Run a morning check for:

Not Registered

Didn't Reboot (day)

Didn't Reboot (week)

Maintenance Mode

License Count

Session Count

vDisk Version Count

PVS Check

#>

$strVerbose = "Yes"

$strLicenseServer = "CitrixLicenseServer"

$strPVSServer = "CitrixPVSServer"

$strErrorValue = "SilentlyContinue"

$ErrorActionPreference = $strErrorValue

$strVerbose = "Yes"

# Date/time variables

$dtmMin = Get-Date '07:00'

$dtmMax = Get-Date '23:00'

$dtmStart = Get-Date

$dtmNow = Get-Date

$dtmToday = $dtmStart

$dtmTodayDateLong = $($dtmToday.ToString("yyyy-MM-dd"))

$dtmTodayDateShort = $($dtmToday.ToShortDateString())

$dtmTodayDayOfWeek = $($dtmToday.DayOfWeek)

$dtmEnd = ""

$strTotalTime = ""

$objTotalReport = @()

# Set console properties

$Host.UI.RawUI.WindowTitle = "XA7.x Morning Server Report, please wait..."

$Host.UI.RawUI.BackgroundColor = "DarkBlue"

$Host.UI.RawUI.ForegroundColor = "Gray"

Clear-Host

# All variables used in script:

$objAllServers = @()

$objReport = @()

$objServersPoweredOff = @()

$objServersInMaintenanceMode = @()

$objServersNotRegistered = @()

$objServersUptimeTooLong = @()

$objServersUptimeOverWeek = @()

$objServersDNSCheckFailed = @()

$objServersStatusUnknown = @()

# Font color for "(requires intervention)"

$strFontAlertColor = "#FF0000"

# Email settings

$strEmailServer = "mail.usa-ed.net"

$strEmailFrom = "email@company.com"

$arrEmailMessage = @()

$strEmailMessage = @()

$strEmailMessage2 = @()

$arrEmailToDwayne = @()

$strEmailSubject = "Citrix Morning Health Check"

$strEmailMessage2 = "Up to date report can be found here: URL to Sharepoint site . This email will stop soon. Please bookmark the link. "

$arrEmailToAll = @('email@company.com', 'email@company.com', 'email@company.com')

$OFS = " <br> "

# File locations

$strFilesLocation = "\\location"

$strSnapInLocation = "\\location"

# Add "Snapin" for uptime

. $strSnapInLocation\General_Functions.ps1 | Out-Null

asnp citrix*

Import-Module VMware.VimAutomation.Core

# ***************************************************************************************************

# ************************************** Variables Setup Ends ***************************************

# ***************************************************************************************************

$VerbosePreference = "Continue"

$vcservers = @("vSphere.domain.com")

# Connects to the Vsphere

set-PowerCLIConfiguration -invalidCertificateAction "ignore" -confirm:$false | Out-Null

Connect-VIServer -Server $vcservers

# ***************************************************************************************************

# *************************************** Functions Starts ******************************************

# ***************************************************************************************************

# Function to send email

Function funSendEmail($funEmailSubject, $funEmailMessage, $funEmailTo) {

Send-MailMessage -To $funEmailTo -Subject $funEmailSubject -From $strEmailFrom -Body $funEmailMessage -SMTPServer $strEmailServer -BodyAsHTML

}

# Function to send email with attachment

Function funSendEmailAttachment($funEmailSubject, $funEmailMessage, $funEmailTo, $funAttachment) {

Send-MailMessage -To $funEmailTo -Subject $funEmailSubject -From $strEmailFrom -Body $funEmailMessage -SMTPServer $strEmailServer -BodyAsHTML -Attachments $funAttachment

}

# ***************************************************************************************************

# **************************************** Functions Ends *******************************************

# ***************************************************************************************************

# ***************************************************************************************************

# ************************************** Script Setup Starts ****************************************

# ***************************************************************************************************

# Create daily and "Reports" folder if it doesn't exist

If ((Test-Path "$strFilesLocation\$dtmTodayDateLong") -ne $TRUE) {

New-Item -ItemType Directory -Path "$strFilesLocation\$dtmTodayDateLong" -Force

}

# ***************************************************************************************************

# *************************************** Script Setup Ends *****************************************

# ***************************************************************************************************

# ***************************************************************************************************

# *********************************** Main Body of Script Starts ************************************

# ***************************************************************************************************

$objAllServers = Get-BrokerMachine -MaxRecordCount 1700 | Sort-Object HostedMachineName

# License Server and Concurrent Connection licensing availability

$strLicenseCount = Get-WmiObject -class "Citrix_GT_License_Pool" -Namespace "ROOT\CitrixLicensing" -ComputerName "$($strLicenseServer)"

$strInUseCount = ($strLicenseCount | Where-Object {$_.InUseCount -gt 0 -and $_.PLD -eq "MPS_ENT_CCU"}).InUseCount

# Check PVS

$strPVSInfo = Invoke-Command -ComputerName $strPVSServer -ScriptBlock {

Import-Module "C:\Program Files\Citrix\Provisioning Services Console\Citrix.PVS.SnapIn.dll"

# Collection names and how many servers using the collection

Get-PvsCollection | Select CollectionName, ActiveDeviceCount

# How many servers are on each pvs server

}

$objPVSDevice = Invoke-Command -ComputerName $strPVSServer -ScriptBlock {

Import-Module "C:\Program Files\Citrix\Provisioning Services Console\Citrix.PVS.SnapIn.dll"

Get-PvsServerInfo

}

$strPVSDeviceInfo = Invoke-Command -ComputerName $strPVSServer -ScriptBlock {

Import-Module "C:\Program Files\Citrix\Provisioning Services Console\Citrix.PVS.SnapIn.dll"

# Collection names and how many servers using the collection

Get-PvsDeviceInfo | Select DeviceName, Type, CollectionName, DiskVersion, DomainControllerName

# How many servers are on each pvs server

}

$strPVSDisk = Invoke-Command -ComputerName $strPVSServer -ScriptBlock {

Import-Module "C:\Program Files\Citrix\Provisioning Services Console\Citrix.PVS.SnapIn.dll"

$strVdisk = (Get-ChildItem F:\Prod -Filter *.vhdx | Select-Object Name).Name.substring(0,7) | Select -Unique

$objvDisk = @()

foreach($strDisk in $strVdisk){

#Write-Output "$strDisk"

$strvDiskCount = 0

$strDiskNum = ($strDisk).substring(0,7)

$strvDiskClean = $strDisk-replace '-'

$objvData = New-Object System.Object

$strvDiskCount = ((Get-ChildItem F:\Prod -Filter "*.*vhdx" | Where {$_ -like "$strDisk*"})).count

$objvData | Add-Member -Type NoteProperty -Name "vDisk" -Value $strvDiskClean

$objvData | Add-Member -Type NoteProperty -Name "vCount" -Value $strvDiskCount

$objvDisk += $objvData

}

RETURN $objvDisk

}

# Get information from each server

$loopCounter = 0

$jobloop = 0

# Sets the end number to count against

$loopEnd = $objAllServers.Count

$maxConcurrentJobs = 100

ForEach ($Server in $objAllServers) {

 

# Informs what server the report is working on for manual testing purposes only

If ($strVerbose -eq "Yes") {

$loopCounter++

Write-Output "Working on server $($($Server.MachineName).Substring("7,")), $loopCounter of $loopEnd"

}

$loopPowerState = $NULL

$loopInMaintenanceMode = $NULL

$loopRegistrationState = $NULL

$loopWindowsConnectionSetting = $NULL

$loopDeliveryGroup = $NULL

$loopUptime = $NULL

$loopUptimeTooLong = $NULL

$loopUptimeTooLongWeek = $NULL

$loopRegistrationState = $($Server.RegistrationState)

$loopDeliveryGroup = $($Server.DesktopGroupName)

$vSphereInfo = $NULL

$objBoundary = $NULL

# Determine if machine is in maintenance mode (true / false)

$loopInMaintenanceMode = $($Server.InMaintenanceMode)

$vSphereResourceInfo = Get-VM $($Server.MachineName).Substring("7,")

#Get-VM | Select-Object -property Name,NumCpu,MemoryGB

# Get vSphere information to add to the report

$vSphereInfo = Get-VMGuest $($Server.MachineName).Substring("7,") | select State, Disks, Toolsversion

$vSphereInfoDisk = $vSphereInfo.Disks

$vSphereInfoDiskC = $vSphereInfoDisk | Where {$_.Path -like "*C*"}

$vSphereInfoDiskD = $vSphereInfoDisk | Where {$_.Path -like "*D*"}

$vSphereInfoDiskCCapacity = [math]::Round($($vSphereInfoDiskC.CapacityGB), 3)

$vSphereInfoDiskCFreeSpace = [math]::Round($($vSphereInfoDiskC.FreeSpaceGB), 3)

$vSphereInfoDiskDCapacity = [math]::Round($($vSphereInfoDiskD.CapacityGB), 3)

$vSphereInfoDiskDFreeSpace = [math]::Round($($vSphereInfoDiskD.FreeSpaceGB), 3)

 

# Determine the machine's registration state (Unregistered, Initializing, Registered, and AgentError), Restart VM if Unregistered and the Vm is on.

If($loopRegistrationState -eq "Unregistered" -and $vSphereInfo.PowerState -eq "Running") {

Restart-Computer -ComputerName $($Server.MachineName).Substring("7,") -Force

#Stop-VM -VM $($Server.MachineName).Substring("7,") -Confirm:$false

#Start-Sleep -Seconds 2

#Start-VM -VM $($Server.MachineName).Substring("7,") -Confirm:$false

}

# Start the VM is powerstate is "NotRunning"

If($vSphereInfo.PowerState -eq "NotRunning") {

Start-VM -VM $($Server.MachineName).Substring("7,") -Confirm:$false

}

 

$strUptime = & C:\Windows\System32\UPTIME.EXE $($Server.MachineName).Substring("7,")

$uptimeDays = (($strUptime.Split(':')[1].split(',')[0]).replace("day(s)"," ")).replace(" ","")

# Get uptime of the VM to determine last boottime and not have been booted in the alotted time

#$uptime = (Get-Stat -Entity $($Server.MachineName).Substring("7,") -Stat sys.uptime.latest -Realtime -MaxSamples 1).value

# Translates to Hours

#$uptimeHours = $uptime/3600

# Translates to Days

#$uptimeDays = $uptimeHours/24

# Check if server has rebooted in last 37 hours

If ( $($uptimeDays) -ge "1") {

$loopUptimeTooLong = "Yes"

} Else {

$loopUptimeTooLong = "No"

}

# Check if server has rebooted in 8 days

If ( $($uptimeDays) -ge "7") {

$loopUptimeTooLongWeek = "Yes"

} Else {

$loopUptimeTooLongWeek = "No"

}

# Check if NetLogin is running, if not, start it

$netlogon = Get-Service -Name Netlogon -ComputerName $($Server.MachineName).Substring("7,")

If ($netlogon.Status -eq "Stopped") {

Start-Service -Name Netlogon

$netlogonStatus = "Stopped"

}Else{

$netlogonStatus = "Running"

}

#Needed for our environment

switch ($server.DesktopGroupName)

{

'Group1' {

$objBoundary = "Info"

}

'Group2' {

$objBoundary = "Info"

}

'group3' {

$objBoundary = "Info"

}

'Group4' {

$objBoundary = "Info"

}

'Group5' {

$objBoundary = "Info"

}

Default {

$NULL

}

}

$strCollectionName = $NULL

switch ($checkdevice.CollectionName)

{

'PROD XAP - vDisk1' {

$strCollectionName = "vDisk1"

}

'PROD XAP - vDisk 3' {

$strCollectionName = "vDisk3"

}

'PROD XAP - vDisk9' {

$strCollectionName = "vDisk9"

}

'PROD XAP - vDisk14' {

$strCollectionName = "vDisk14"

}

'PROD-XAP-Staging' {

$strCollectionName = "Staging"

}

'PROD XAP1 - vDisk4M' {

$strCollectionName = "vDisk4M"

}

Default {

$NULL

}

}

 

# Get "Used for" Inormation

If($($Server.MachineName).Substring("7,") -like "P*") {

$strUsedfor = "Production"

}ElseIf($($Server.MachineName).Substring("7,") -like "N*") {

$strUsedfor = "Dev"

}

# Get PVS information if applicatble

$checkdevice = $strPVSDeviceInfo | Where {$_.devicename -eq "$($server.machinename.substring("7,"))"}

# If PVS, set type "Production, Maintenance, Test

If($checkdevice -ne $null) {

switch ($checkdevice.type) {

'0' {$checkdevice.type = "Production"}

'1' {$checkdevice.type = "Test"}

'2' {$checkdevice.type = "Maintenance"}

}

# Add to the $objReport if PVS

$objData = New-Object System.Object

$objData | Add-Member -Type NoteProperty -Name "Name" -Value $($Server.MachineName).Substring("7,")

$objData | Add-Member -Type NoteProperty -Name "IP Address" -Value $Server.IPAddress

$objData | Add-Member -Type NoteProperty -Name "ServerState" -Value $vSphereInfo.State

$objData | Add-Member -Type NoteProperty -Name "RegistrationState" -Value $loopRegistrationState

$objData | Add-Member -Type NoteProperty -Name "InMaintenanceMode" -Value $loopInMaintenanceMode

$objData | Add-Member -Type NoteProperty -Name "Delivery Group" -Value $loopDeliveryGroup

$objData | Add-Member -Type NoteProperty -Name "Collection Name" -Value $strCollectionName

$objData | Add-Member -Type NoteProperty -Name "Type" -Value $checkdevice.type

$objData | Add-Member -Type NoteProperty -Name "Disk Version" -Value $checkdevice.Diskversion

$objData | Add-Member -Type NoteProperty -Name "NetLogon" -Value $netlogonStatus

$objData | Add-Member -Type NoteProperty -Name "VMware Tools Version" -Value $vSphereInfo.Toolsversion

$objData | Add-Member -Type NoteProperty -Name "Boottime (Days)" -Value $uptimeDays

$objData | Add-Member -Type NoteProperty -Name "UptimeTooLong" -Value $loopUptimeTooLong

$objData | Add-Member -Type NoteProperty -Name "UptimeOverWeek" -Value $loopUptimeTooLongWeek

$objData | Add-Member -Type NoteProperty -Name "C Drive Capacity (GB)" -Value $vSphereInfoDiskCCapacity

$objData | Add-Member -Type NoteProperty -Name "C Drive FreeSpace (GB)" -Value $vSphereInfoDiskCFreeSpace

$objData | Add-Member -Type NoteProperty -Name "D Drive Capacity (GB)" -Value $vSphereInfoDiskDCapacity

$objData | Add-Member -Type NoteProperty -Name "D Drive FreeSpace (GB)" -Value $vSphereInfoDiskDFreeSpace

$objData | Add-Member -Type NoteProperty -Name "CPU" -Value $($vSphereResourceInfo.NumCpu)

$objData | Add-Member -Type NoteProperty -Name "Memory" -Value $($vSphereResourceInfo.MemoryGB)

$objData | Add-Member -Type NoteProperty -Name "Assignment group" -Value "Citrix.Admin"

$objData | Add-Member -Type NoteProperty -Name "Class" -Value "Citrix XenAPP or Presentation Server"

$objData | Add-Member -Type NoteProperty -Name "Description" -Value "CITRIX($($server.DesktopGroupName))"

$objData | Add-Member -Type NoteProperty -Name "Boundary" -Value $objBoundary

$objData | Add-Member -Type NoteProperty -Name "Used for" -Value $strUsedfor

}Else{

# Add to the $objReport if Static

$objData = New-Object System.Object

$objData | Add-Member -Type NoteProperty -Name "Name" -Value $($server.machinename.substring("7,"))

$objData | Add-Member -Type NoteProperty -Name "IP Address" -Value $Server.IPAddress

$objData | Add-Member -Type NoteProperty -Name "ServerState" -Value $vSphereInfo.State

$objData | Add-Member -Type NoteProperty -Name "RegistrationState" -Value $loopRegistrationState

$objData | Add-Member -Type NoteProperty -Name "InMaintenanceMode" -Value $loopInMaintenanceMode

$objData | Add-Member -Type NoteProperty -Name "Delivery Group" -Value $loopDeliveryGroup

$objData | Add-Member -Type NoteProperty -Name "Collection Name" -Value "Static"

$objData | Add-Member -Type NoteProperty -Name "Type" -Value "Static"

$objData | Add-Member -Type NoteProperty -Name "Disk Version" -Value "Static"

$objData | Add-Member -Type NoteProperty -Name "NetLogon" -Value $netlogonStatus

$objData | Add-Member -Type NoteProperty -Name "VMware Tools Version" -Value $vSphereInfo.Toolsversion

$objData | Add-Member -Type NoteProperty -Name "Boottime (Days)" -Value $uptimeDays

$objData | Add-Member -Type NoteProperty -Name "UptimeTooLong" -Value $loopUptimeTooLong

$objData | Add-Member -Type NoteProperty -Name "UptimeOverWeek" -Value $loopUptimeTooLongWeek

$objData | Add-Member -Type NoteProperty -Name "C Drive Capacity (GB)" -Value $vSphereInfoDiskCCapacity

$objData | Add-Member -Type NoteProperty -Name "C Drive FreeSpace (GB)" -Value $vSphereInfoDiskCFreeSpace

$objData | Add-Member -Type NoteProperty -Name "D Drive Capacity (GB)" -Value $vSphereInfoDiskDCapacity

$objData | Add-Member -Type NoteProperty -Name "D Drive FreeSpace (GB)" -Value $vSphereInfoDiskDFreeSpace

$objData | Add-Member -Type NoteProperty -Name "CPU" -Value $($vSphereResourceInfo.NumCpu)

$objData | Add-Member -Type NoteProperty -Name "Memory" -Value $($vSphereResourceInfo.MemoryGB)

$objData | Add-Member -Type NoteProperty -Name "Assignment group" -Value "Citrix.Admin"

$objData | Add-Member -Type NoteProperty -Name "Class" -Value "Citrix XenAPP or Presentation Server"

$objData | Add-Member -Type NoteProperty -Name "Description" -Value "CITRIX($($server.DesktopGroupName))"

$objData | Add-Member -Type NoteProperty -Name "Boundary" -Value $objBoundary

$objData | Add-Member -Type NoteProperty -Name "Used for" -Value $strUsedfor

}

$objReport += $objData

#Still working on this

<# Restarts VMs if not been rebooted over 37 hours, only after 11PM or before 7AM. It will not do this part if between those times

If(!$dtmNow.TimeOfDay -gt $dtmMin.TimeOfDay -and $dtmNow.TimeOfDay -lt $dtmMax.TimeOfDay) {

If ($objData.UptimeTooLong -eq "Yes") {

Restart-VM -VM $objData.Name -Confirm:$false

}

}#>

}

<#do {

Write-Output " Waiting"

}

until (Get-Job | Where {$_.State -notcontains )

Receive-Job -Name "Job106"

#>

$unregisteredafter = Get-BrokerMachine -MaxRecordCount 1700 | Where {$_.RegistrationState -eq "Unregistered"}

# Determine counts

$objServersPoweredOff = $objReport | Where {$_.ServerState -ne "Running" -and $_.InMaintenanceMode -ne $true}

$objServersInMaintenanceMode = $objReport | Where {$_.InMaintenanceMode -eq $true}

$objServersNotRegistered = $objReport | Where { ($_.RegistrationState -eq "Unregistered" -or $_.RegistrationState -eq "AgentError")}

$objServersUptimeTooLong = $objReport | Where {$_.UptimeTooLong -eq "Yes"}

$objServersUptimeOverWeek = $objReport | Where {$_.UptimeOverWeek -eq "Yes"}

$objServersStatusUnknown = $objReport | Where {$_.Boottime -eq $null -and $_.RegistrationState -eq "Registered" -and $_.InMaintenanceMode -eq $false}

$objServersNetLogonStatus = $objReport | Where { $_.NetLogon -eq "Stopped"}

$intSessionCount = (Get-BrokerSession -MaxRecordCount 2000 -SessionState active).count

$dtmEnd = Get-Date

 

 

# ***************************************************************************************************

# ************************************ Main Body of Script Ends *************************************

# ***************************************************************************************************

# ***************************************************************************************************

# ************************************** Post Script Starts *****************************************

# ***************************************************************************************************

 

# Create email

If ($strTesting -eq "Yes") {

$arrEmailMessage = @() # Temp for testing

}

$arrEmailMessage += @"

<html>

<body>

<title>Server Health Check</title>

<b>$dtmTodayDayOfWeek ($dtmTodayDateShort) Server Health Check Follows: </b>

Up to date vDisk report can be found here: URL Location of the updated CSV file. I use Microsoft Flow to move from my MorningReport folder in outlook to our SharePoint site

<br>

"@

# Overview

$arrEmailMessage += "<b>Overview:</b>"

If ( $($objServersNotRegistered.Count) -ne 0 ) {

$arrEmailMessage += "Not Registered before reboot: $($objServersNotRegistered.Count) <font color=""$strFontAlertColor""><b>(Rebooting, will reflect on Not registered after reboot)</b></font>"

$arrEmailMessage += "Not Registered after reboot: $($unregisteredafter.Count)"

} Else {

$arrEmailMessage += "Not Registered (No actions needed): $($objServersNotRegistered.Count)"

}

$arrEmailMessage += "NetLogon Stopped: $($objServersNetLogonStatus.count)"

If ( $($objServersUptimeOverWeek.Count) -ne 0 ) {

$arrEmailMessage += "Didn't Reboot (Week): $($objServersUptimeOverWeek.Count) <font color=""$strFontAlertColor""><b>(requires intervention)</b></font>"

} Else {

$arrEmailMessage += "Didn't Reboot (Week): $($objServersUptimeOverWeek.Count)"

}

If ( $($objServersUptimeTooLong.Count) -ne 0 ) {

$arrEmailMessage += "Didn't Reboot (Day): $($objServersUptimeTooLong.Count) <font color=""$strFontAlertColor""><b>(requires intervention)</b></font>"

} Else {

$arrEmailMessage += "Didn't Reboot (Day): $($objServersUptimeTooLong.Count)"

}

$arrEmailMessage += "In Maintenance Mode: $($objServersInMaintenanceMode.Count)"

$arrEmailMessage += "License Count: $($strInUseCount)"

$arrEmailMessage += "Session Count: $($intSessionCount)"

#$arrEmailMessage += "<br>"

$arrEmailMessage += "<b>Details Follow:</b>"

#PVS

$arrEmailMessage += "<b>PVS Health Check:</b>"

ForEach($PVS in $objPVSDevice) {

$arrEmailMessage += "$($PVS.name) has $($PVS.DeviceCount) Servers"

}

$arrEmailMessage += "<br>"

$arrEmailMessage += "<b>vDisk Version Count:</b>"

ForEach($vDisk in $strPVSDisk) {

$arrEmailMessage += "$($($vDisk.vDisk).Replace("-"," ")) has $($vDisk.vCount) Disks"

}

$arrEmailMessage += "<br>"

$arrEmailMessage += "<b>PVS Collection Count:</b>"

ForEach($Collection in $strPVSInfo) {

$arrEmailMessage += "$($Collection.CollectionName) has $($Collection.ActiveDeviceCount) Active Servers"

}

$arrEmailMessage += "<br>"

# Servers not registered and not in maintenance mode

$arrEmailMessage += "<b>Powered ON, not registered, and not in maintenance mode) ($($objServersNotRegistered.Count)): </b>"

#$arrEmailMessage += "<b>Servers have been rebooted as a proactive measure. </b>"

$arrEmailMessage += $($objServersNotRegistered.name)

$arrEmailMessage += "<br>"

# Servers with Netlogon Stopped but was turned on

$arrEmailMessage += "<b>NetLogon Stopped but was started in the script: $($objServersNetLogonStatus.count) :</b>"

$arrEmailMessage += "$($objServersNetLogonStatus.name)"

$arrEmailMessage += "<br>"

# Servers powered off and not in maintenance mode

$arrEmailMessage += "<b>Powered OFF, and not in maintenance mode ($($objServersPoweredOff.Count)): </b>"

$arrEmailMessage += $($objServersPoweredOff.name)

$arrEmailMessage += "<br>"

# Servers in maintenance mode

$arrEmailMessage += "<b>In Maintenance Mode: ($($objServersInMaintenanceMode.Count)):</b>"

$arrEmailMessage += $($objServersInMaintenanceMode.name)

$arrEmailMessage += "<br>"

# Servers didn't reboot in a week

$arrEmailMessage += "<b> Didn't Reboot in the last week (8 days) ($($objServersUptimeOverWeek.Count)): </b>"

#$arrEmailMessage += "<b>Servers have been rebooted as a proactive measure. </b>"

$arrEmailMessage += $($objServersUptimeOverWeek.name)

$arrEmailMessage += "<br>"

# Servers didn't reboot

$arrEmailMessage += "<b>Didn't Reboot in the last 37 hours ($($objServersUptimeTooLong.Count)): </b>"

#$arrEmailMessage += "<b>Servers have been rebooted as a proactive measure. </b>"

$arrEmailMessage += $($objServersUptimeTooLong.name)

$arrEmailMessage += "<br>"

 

 

 

 

$arrEmailMessage += @"

<br>

Report completed at: $(Get-Date -Format "hh:mm tt")<br>

Run time: $("{0:N2}" -f (New-TimeSpan -Start $dtmStart -End $dtmEnd).TotalMinutes) minutes<br>

</body>

</html>

"@

$strEmailMessage = [string]$arrEmailMessage

$objReport | Export-Csv -Path "$strFilesLocation\$dtmTodayDateLong\$dtmTodayDateLong,ServerReport.csv" -NoTypeInformation -Force

$objReport | Export-Csv -Path "$strFilesLocation\$dtmTodayDateLong\ServerReport.csv" -NoTypeInformation -Force

$funAttachment = "$strFilesLocation\$dtmTodayDateLong\ServerReport.csv"

# Email report

funSendEmail $strEmailSubject $strEmailMessage $arrEmailToAll

funSendEmailAttachment $strEmailSubject $strEmailMessage $arrEmailToAll $funAttachment

If ($strTesting -ne "Yes") {

# Save HTML email

Set-Content -Path "$strFilesLocation\$dtmTodayDateLong\$dtmTodayDateLong, XA7.x_Morning_Server_Email.html" -Value $strEmailMessage

}

# Save report

$objReport | Export-Csv -Path "$strFilesLocation\$dtmTodayDateLong\$dtmTodayDateLong, XA7.x_Morning_Server_Report.csv" -NoTypeInformation -Force

# ***************************************************************************************************

# *************************************** Post Script Ends ******************************************

# ***************************************************************************************

Link to comment
  • 0

I too have been writing Powershell scripts...  Right now I am working on a script to make sure our most used applications will launch okay from our Xenapp servers.  I want to test launch apps from our 23 servers.  I find a couple apps I cannot launch with my Powershell script, but launch fine from Receiver/Workspace.  I use the following:

 

$ICA.Connect()

write-host "LogErrors:  " $ICA.LogErrors

write-host "LogFile:  " $ica.LogFile

write-host "ReadyState:  " $ica.ReadyState

write-host "GetLastError:  " $ica.GetLastError()
#
$Trigger = Wait-Event  -SourceIdentifier ICA_OnLogon -TimeOut 60
if ($Trigger -ne $null) {
    Write-Host (Get-Date) " Login successful."
    }
else {
    Write-Host (Get-Date) " Login failed."
    }

$a = 0
do {
    $a++
    sleep 1
    } until ($ICA.Connected -eq $True -or $a -ge 60)
$b = $ICA.Connected

 

I find the Wait-Event never sees a sucessful login, but my loop to sleep until $ICA.Connected is true does work.  But like I said I have two apps that never launch, the $ICA.Connected never returns true.  I get the Citrix launching window, but the apps never launches.  I've checked spelling of the application name, even cut and pasted the name from Studio.  I get the same result if I use a bogus application name.  So my question is, what can I do to see the result of the $ICA.Connect() that will tell me what is going wrong?

 

Thanks,

Tim.

Link to comment
  • 0

Hi,

 

Quick one i knocked up to email our support desk at the end of each day to ensure those that `left` a host in maintenance brings it back out before the next day`s production!

 

Add-PSSnapin Citrix.*;

$scr = Get-BrokerMachine | where { $_.InMaintenanceMode } | ft MachineName, InMaintenanceMode | out-string

$FromAddress = "sender@address.com"

$ToAddress = "recipient@address.com"

$MessageSubject = "Daily APP Host Maintenance Mode Checks"

$SendingServer = "smtp.domain.local"

$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject,$scr

$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer

$SMTPClient.Send($SMTPMessage)

 

Cheers,

Link to comment
  • 0
On 9/4/2018 at 7:13 PM, Balaji Muthukrishnan said:

Please share the power shell command line equivalent for force rebooting a hung VM using xe cmd line.

 

xe vm-shutdown -–force uuid=[UUID for VM]

 

Need equivalent cmd for powershell XS 7.0 to remotely force reboot or shutdown a hung VM

This is a part of the script we use to reboot those Xenserver 2008R2 guests which did not survive the nightly reboot, normally stuck on "Restarting" and need to be kicked.

 

# Find all servers which are unregistered, but powered on and no sessions
$Unregistered = Get-BrokerMachine -AdminAddress $DDCname | where {$_.RegistrationState -notlike "Registered" -and $_.SessionsEstablished -eq "0" -and $_.PowerState -eq "On" -and $_.OSType -like "*2008*"}

# Xenserver creds
# (Use whatever method to get and store credentials for the Xenservers)

 

# Import XenServer modules
import-module XenServerPSModule
#############

# Run actions on target servers
foreach ($VM in $Unregistered){
Write-Verbose "Processing server $($VM.HostedMachineName)" -Verbose

#Connect to XenServer and get correct Poolmaster... a bit slow, but it works
$Xenhost = $VM.HostingServerName
  Try {
        $Session = Connect-XenServer -Url "https://$Xenhost" -UserName $Xusername -Password $password -NoWarnCertificates -SetDefaultSession
    } Catch [XenAPI.Failure] {
        [string]$PoolMaster = $_.Exception.ErrorDescription[1]  
        Write-verbose "$($Xenhost) is slave, Master was identified as $($PoolMaster), trying to connect" -Verbose
        $Session = Connect-XenServer -url "http://$PoolMaster" -UserName $Xusername -Password $password -NoWarnCertificates -SetDefaultSession
    }

# force Reboot VM
Write-Verbose "Rebooting $($VM.HostedMachineName)" -Verbose
Invoke-XenVM -Name $VM.HostedMachineName -XenAction HardReboot

}
 

Link to comment
  • 0

i am able to increase vCPU and RAM for the VMs in AHV Clusters but facing challenges in extending the C drive space. I am able to add additional disk but not able to extended existing disk size. not sure if am using the correct DTO. pls help...

 

$diskUpdateSpec = New-NTNXObject -Name VmDiskUpdateDTO
$diskUpdateSpec.diskId = "000-3b-2-00-0000014::b9e-05-42-a8-661f"
$diskUpdateSpec.diskUuid = "b91-058-43-a81-661f"
$diskUpdateSpec.updateSpec = "15000"
Set-NTNXVMDisk -Vmid "cb6b0132fd" -UpdateSpec $diskCreateSpec -DiskId "000-3b-2-00-0000014::b9e-05-42-a8-661f" -Diskaddress /DP03D-NTNX-CTX-LUN01/.acropolis/vmdisk/b91-058-43-a81-661f

 

 

Exception setting "updateSpec": "Cannot convert the "15000" value of type "System.String" to type "Nutanix.Prism.DTO.Acropolis.VMDiskUpdateSpecDTO"."
At line:6 char:1
+ $diskUpdateSpec.updateSpec = "15000"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting
 

Exception setting "updateSpec": "Cannot convert the "15000" value of type "System.Int32" to type "Nutanix.Prism.DTO.Acropolis.VMDiskUpdateSpecDTO"."
At line:8 char:1
+ $diskUpdateSpec.updateSpec = 15000
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...