16
Mar 18

The background of this script is I wanted a way to quickly determine where a said VDI device lived within our environment and if a user was logged in. Meaning, if we had a said machine I could query for it and find the following:

  • Logged in User
  • DDC connection
  • ESX Host
  • StoreFront Server
  • Delivery Group
  • Ip Address
  • PVS Catalog Name
  • PVS Server Connection
  • PVS VHD Image
  • 
    param(
       [array] $VDIs
    )
    
    write-host $VDI
    foreach($vdi in $VDIs){
    Get-BrokerDesktop -adminaddress DDCServerName -hostedMachineName $VDI | 
    FT HostedMachineName,
    SessionUserName,
    ControllerDNSName,
    HostingServerName,
    LaunchedViaHostName,
    DesktopGroupName,
    IPAddress ;
    
    
    Invoke-Command -ComputerName xen-sal-pvs1 {param([string] $VDI = $VDIs)asnp Citrix.* ; Get-PvsDeviceInfo -DeviceName $VDI | 
        FT DeviceName,
        CollectionName,
        ServerIpConnection,
        ServerName,
        DiskFileName} -ArgumentList $VDI
    
    }
    

    SAMPLE OUTPUT

    
    PS C:\Temp> .\CitrixFindMachine.ps1 'vdiLondon043','vdiLondon101'
    
    HostedMachineName SessionUserName            ControllerDNSName             HostingServerName           	LaunchedViaHostName           	DesktopGroupName        		IPAddress
    ----------------- ---------------            -----------------             -----------------           -------------------           	----------------        	 ---------
    vdiLondon043     contoso\Donald.Trump 	     CTX-LND-DC2.ad.contoso.com    LNDesx207.ad.contoso.com 	CTX-LND-SF1.ad.contoso.com 		Win 10 Adobe Acrobat Pro 		10.0.0.89
    
    DeviceName    CollectionName       ServerIpConnection ServerName   DiskFileName
    ----------    --------------       ------------------ ----------   ------------
    vdiLondon043 Windows 10 Adobe Pro  10.0.0.241        CTX-LND-PVS2 Win10 x64 Adobe Pro_2018-01-31_23-06-31.vhd
    
    ***************************************
    
    HostedMachineName SessionUserName ControllerDNSName             HostingServerName           LaunchedViaHostName DesktopGroupName IPAddress
    ----------------- --------------- -----------------             -----------------           ------------------- ---------------- ---------
    vdiLondon101                         CTX-LND-DC2.ad.contoso.com LNDesx202.ad.contoso.com                     Win10 Desktop    10.0.0.149
    
    
    DeviceName CollectionName ServerIpConnection ServerName   DiskFileName
    ---------- -------------- ------------------ ----------   ------------
    vdiLondon101  Windows 10     10.0.0.241        CTX-LND-PVS2 Win10 x64 Basic Template_2018-01-31_17-59-55.vhd
    
    
    5
    Mar 18
    ##Add all Citrix snap-ins
    asnp Citrix.*
    
    ##Check for VMs 
    
    (Get-BrokerMachine -Filter {
    RegistrationState -ne 'Registered' `
    -AND FaultState -ne 'None' `
    -AND MachineInternalState -eq 'Unregistered' `
    -AND PowerState -ne 'Off' `
    -AND InMaintenanceMode -ne 'True' `
    -AND SessionUserName -eq $null}|
    Select-Object HostedMachineName, DesktopGroupName,PowerState,SessionUserName,RegistrationState,InMaintenanceMode|FT -A)

    SAMPLE OUTPUT

    HostedMachineName DesktopGroupName   PowerState SessionUserName RegistrationState InMaintenanceMode
    ----------------- ----------------   ---------- --------------- ----------------- -----------------
    VDILND037         Win10 London               On                      Unregistered             False
    VDILND039         Win10 London               On                      Unregistered             False
    VDILND060         Win10 London               On                      Unregistered             False
    VDILND065         Win10 London               On                      Unregistered             False
    VDILND075         Win10 London               On                      Unregistered             False
    VDILND079         Win10 London               On                      Unregistered             False
    VDILND082         Win10 London               On                      Unregistered             False
    VDILND086         Win10 London               On                      Unregistered             False
    VDILND095         Win10 London               On                      Unregistered             False
    VDILND098         Win10 London               On                      Unregistered             False
    VDILND238         Win10 London               On                      Unregistered             False
    VDI-IS-TST004     IS Win10Test Group         On                      Unregistered             False
    VDISAL342         Win10 Desktop              On                      Unregistered             False
    VDALND667         Win10 Desktop         Unknown                      Unregistered             False
    
    
    11
    Mar 16
    
    #==================================================================
    #==== I needed a quick one liner to check the eventlogs for an application that stopped.
    #==== Script looks at a text file with server names then scans both system and application log for the last day for messages
    #==================================================================
    
    
    $servers = Get-Content -Path C:\PowershellScripts\Servers.txt
    ForEach ($server in $servers)
    {
    	Get-Eventlog -ComputerName $server -LogName system -EntryType information -After (Get-Date).AddDays(-1) | where-object { $_.Message -Like "*Stopped*" } | select MachineName, TimeWritten, message
    	Get-Eventlog -ComputerName $server -LogName application -EntryType information -After (Get-Date).AddDays(-1) | where-object  { $_.Message -Like "*stopping*" } | select MachineName, Source, TimeWritten, message
    }
    
    
    20
    May 15
    #==================================================================
    #==== I needed a script or command line to check memory for a set of processes.
    #==================================================================
    
    PS C:\ get-process -computername ServerName1,ServerName2,ServerName3,ServerName4 Notepad,jbosssvc,Outlook,WINWORD|select name,@{l="WorkingSet(MB)}"; e={$_.WorkingSet64 / 1mb}},machinename |sort-object -property Name |ft -AutoSize
    
    Name WorkingSet(MB)} MachineName
    ---- --------------- -----------
    Outlook 30.06640625 ServerName4
    Outlook 28.8203125 ServerName3
    Outlook 29.53125 ServerName2
    Outlook 31.00390625 ServerName1
    jbosssvc 2.78125 ServerName3
    jbosssvc 2.765625 ServerName4
    jbosssvc 2.76953125 ServerName2
    jbosssvc 2.76953125 ServerName1
    Notepad 20.6484375 ServerName3
    Notepad 18.9453125 ServerName4
    Notepad 18.8828125 ServerName2
    Notepad 128.2734375 ServerName1
    WINWORD 146.81640625 ServerName3
    WINWORD 134.51953125 ServerName4
    WINWORD 270.34765625 ServerName1
    WINWORD 122.6875 ServerName2
    
    
    
    
    20
    May 15
    #==================================================================
    #==== Simple one liner to run a query for printers to see if things change.
    #==== I needed something I could run to see if the default printer changed.
    #==================================================================
    PS C:\while ($true) {Get-WmiObject -Class Win32_printer | select Name, Default| ft -autosize;start-sleep 5}
    
    Name Default
    ---- -------
    \\PRINTSRVTP01\HP_3505 True
    
    Name Default
    ---- -------
    \\PRINTSRVTP01\HP_3505 True
    
    27
    Jan 15

    The background for this post was I needed to uninstall our software application(s) from multiple servers and each server could have multiple components installed.

    #==================================================================
    #==== Must have a text file with servers names in it to run against
    #==== Be careful...this scripts just goes and executes....be careful with keeping server names in the txt file.
    #==================================================================
    
    $servers = get-content -Path "C:\ScriptyBits\ServerNames.txt"
    ForEach ($server in $servers){
    $apps=(gwmi win32_product -CN $server | where-object {$_.Name -match "Awesome Application One" -or $_.Name -match "Awesome Application Two"})
    ForEach($app in $apps){
    $app.Uninstall()
    }
    }
    

    The above script worked just fine. However, I often setup development environments and rapidly iterate through code versions in which I need to quickly uninstall/re-install our software.

    Rather than having to explicitly name each application we install using the "-match" switch I converted it to a use the "-like" switch. This allowed me to point to a list of servers and assuming I had admin rights over all of them it would allow me to uninstall the applications by using wildcards "*"

    #==================================================================
    #==== Must have a text file with servers names in it to run against
    #==== Be careful...this scripts just goes and executes....be careful with keeping server names in the txt file.
    #==================================================================
    
    $servers = get-content -Path "C:\ScriptyBits\ServerNames.txt"
    
    ForEach ($server in $servers){
    $apps=(gwmi win32_product -CN $server | where-object {$_.Name -Like "*Awesome*"})
    write-host Connecting to $server
    ForEach($app in $apps){
    write-host Uninstalling $app
    $app.Uninstall()
    }
    }
    
    12
    Apr 14

    The background on this script is I needed a way to quick verify software versions of beta code installed on my system. Our software installs in several directories with multiple .EXE's in each directory. All executables are contained in a root directory, but I wanted a quick way to search all directories to verify installation was running on the correct version. Less time fighting with developers about me having the wrong version. <insert happy face here> This little script saves me tons of time as I have about 15 servers I run this on and it outputs to a text file very quickly.  I learned a lot on this script as I was not that familiar with invoke-command and it was cool to get it going.

    $servers = Get-Content -Path C:\PowershellScripts\Servers.txt
    $out = ForEach ($server in $servers) 
         { invoke-command -computername $server {Get-ChildItem "C:\Program Files\ccleaner\" -Include *.exe -Recurse |
         Select-Object -ExpandProperty VersionInfo | 
         select-object FileDescription, OriginalFilename, FileVersion, @{Name='ServerName';Expression={ $env:COMPUTERNAME }} | 
        ft -AutoSize
        }} 
    $out|Out-File C:\PowershellScripts\Versions.log

    Sample output:

    FileDescription              OriginalFilename     FileVersion ServerName 
    ---------------              ----------------     ----------- ---------- 
    Agent Application            Agent.exe            1,0,0,14873 SVR01
    DataGatherNET                DataGatherNET.exe    1,0,0,14873 SVR01
    LoggingService Application   Logger.exe           1,0,0,14873 SVR01
    JBoss Service wrapper        jbosssvc.exe         1.2.4.0     SVR01
    JBoss Web Service wrapper    jbossweb.exe         2.0.4.1     SVR01
    JBoss Web Service manager    jbosswebw.exe        2.0.4.1     SVR01
    4
    Apr 14

    I work at a software company and sometimes all I do is install and uninstall our product to test new versions. I wanted to speed things up a little and for my little dev environment write a script to call the uninstall process depending on which OS version was running on the target device. It was an interesting find for me because some of my target devices are WYSE thinclients running Windows Embedded (old....think xp). The process for looking for applications installed on a Windows 7 device and my lovely WYSE device are different. Win7 can use the common Win32_Product whereas the WYSE device I had to use WMI to call Win32Reg_AddRemovePrograms to find my application. Thought process for script

      Target a server
      Check version of OS running
      if running Win7 -> run the uninstall and reboot
      If running WinXP -> run the uninstall and reboot
    param([string]$strComputer ="%1")
     
    $CheckOS =(Get-WmiObject-Class win32_OperatingSystem -namespace"root\CIMV2"-ComputerName $strComputer).caption.trim()
    Write-Host=========================================================
    Write-Host Going against $strComputer to process the Uninstall
    Write-Host=========================================================
    	
    	If($CheckOS -eq "Microsoft Windows 7 Professional")
    		{
    			Write-Host=========================================================
    			write-host $strComputer "has $CheckOS installed"Write-Host
    			write-host RunningUninstall on $strComputer
    			Write-Host=========================================================
    		Get-WmiObject-NameRoot\Cimv2 -classWin32_Product–computername $strComputer |Where-Object{$_.Name-like "Blah*"}|
    			foreach-object-process {$_.Uninstall()}Start-Sleep-Seconds 5 
    			
    			Write-Host=========================================================
    			Write-Host
    			Write-Host $strComputer is going to reboot now
    			Write-Host
    			Write-Host=========================================================
    			Restart-Computer-cn $strComputer -Force
    		}
    	Else
    		{
    			Write-Host=========================================================
    			write-host $strComputer "has $CheckOS installed"
    			Write-Host
    			write-host RunningUninstall on $strComputer
    			Write-Host=========================================================
    	
    	$ProdID = $null
    	$prodid =(get-wmiobject -OutVariable prdid -ClassWin32Reg_AddRemovePrograms -ComputerName rob_wyse |where{$_.Displayname-like "Blah*"}|selectProdID).ProdIdIf($ProdID)
    		{
    			Foreach($PrdID in $ProdID)
    		{
    			start-process psexec -argumentlist "-accepteula \\$strComputer msiexec /X$PrdID /q /norestart"-PassThru
    			Write-Host=========================================================
    			Write-Host
    			Write-Host $strComputer is going to reboot now
    			Write-HostWrite-Host=========================================================Start-Sleep30Restart-Computer-cn $strComputer
    		}
    		}
    		}
    
    4
    Apr 14

    At my company we are about to perform and full power shutdown and I wanted to create a script to shutdown the servers.  I have never used test-connection before so this is what I came up with.

    $servers = get-content -path 'c:\rcj\scripts\powershell\servers.txt'
    $outfile = 'c:\rcj\scripts\powershell\servershutdownresults.txt'
    foreach($server in $servers)
    {
    if(test-connection $server -count 1 -quiet)
    {
    write-output "$server is pingable" | out-file -append -filepath $outfile
    }
    else
    {
    write-output "$server is down" | out-file -append -filepath $outfile
    }
    }