On which RDS server my servers are connected to ? (Powershell)

Brahms 1 Reputation point
2022-06-14T21:11:22.05+00:00

Hi,
I'am trying to report info about RDS server used by certain computers on my environnement. I have a peace of code that is doing the trick but somehow it behaves weird. I would like to build an output like following :

Computername RDSserver LicensingName LicensingType
server1 rds-server1 per user 4
server2 rds-server1 per user 4
...
server n

Actually my output is like following :

RDSserver
LicensingType
LicensingName
Computername

Even if the variable $result is populated correctly, When I trie to display $result.GetSpecifiedLicenseServerList().SpecifiedLSList i got an error :

Method invocation failed because [Deserialized.System.Management.ManagementObject#Root\CIMV2\TerminalServices\Win32_TerminalServiceSetting] does not contain a method named 'GetSpecifiedLicenseServerList'.
At line:1 char:1

  • $result.GetSpecifiedLicenseServerList().SpecifiedLSList
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • CategoryInfo : InvalidOperation: (GetSpecifiedLicenseServerList:String) [], RuntimeException
  • FullyQualifiedErrorId : MethodNotFound

Here is the code bellow :

$computers = Get-Content -Path c:\temp\rds-input-list.txt  

$RDSADGROUP = "Remote_Desktop_Services"  
$computers = (Get-ADGroupMember -Identity $ADGROUP).name   
#  
$objresult = @()  
$result = @()  
Foreach ($computer in $computers) {  

        Try {  
        Invoke-command -ComputerName $computer -scriptblock {   
        $result = gwmi -namespace "Root/CIMV2/TerminalServices" Win32_TerminalServiceSetting   
        $result.GetSpecifiedLicenseServerList().SpecifiedLSList  
        $result.LicensingType  
        $result.LicensingName   
        $result.ServerName  
        } -ErrorAction SilentlyContinue  

        $objresult += $result  

        }  

        Catch{  
            Write-Output "`nError Message: " $_.Exception.Message  
            Write-Output "`nError Item Name: "$_.Exception.ItemName  
        }  

}    

$objresult  

Thank your so much for your help.

Remote Desktop
Remote Desktop
A Microsoft app that connects remotely to computers and to virtual apps and desktops.
4,713 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,625 questions
0 comments No comments
{count} votes

6 answers

Sort by: Most helpful
  1. Rich Matheisen 47,596 Reputation points
    2022-06-14T21:34:10.383+00:00

    Does this produce the results you wanted?

    $RDSADGROUP = "Remote_Desktop_Services"   
    (Get-ADGroupMember -Identity $ADGROUP).name |  
    Foreach-Object{   
        Try {   
            Invoke-Command -ComputerName $_ -scriptblock {   
                    $result = gwmi -namespace "Root/CIMV2/TerminalServices" Win32_TerminalServiceSetting  
                    [PSCustomObject]@{  
                        SpecifiedLSList = $result.GetSpecifiedLicenseServerList().SpecifiedLSList  
                        LicensingType   = $result.LicensingType  
                        LicensingName   = $result.LicensingName   
                        ServerName      = $result.ServerName  
                    }  
                } -ErrorAction STOP             # SilentlyContinue won't cause the "Catch" block to execute if Invoke-Command fails   
            }   
            Catch{          # This will result in two lines of text being present in the midst of the results of the successful Invoke-Command outputs  
                            # which will probably mess up the way they're displayed  
                Write-Output "nError Message: " $.Exception.Message  
                Write-Output "`nError Item Name: "$.Exception.ItemName  
            }  
    }  
    
    0 comments No comments

  2. Brahms 1 Reputation point
    2022-06-14T23:48:19.833+00:00

    Hi Rich ! Thank you so much for your time ! Really appreciated.

    Well your feedback gave me some ideas, i modified the code a bit it shows the output one the correct way i mean, but i cant aggregate the data to have only one header and then all data grabbed by the report.

    Here is the current output, i have bloch with headers repeating each time, i want to get rid of that. The output of my invoke-command is an array so it should work normally ?

    211428-capture-rds-output.jpg

    211472-capture-rds-output2.jpg

    Here is my modified code :

    $RDSADGROUP = "Remote_Desktop_Services"   
    $outputobj = @()  
      
     $scriptblock = { $result = gwmi -namespace "Root/CIMV2/TerminalServices" Win32_TerminalServiceSetting  
                     [PSCustomObject]@{  
                         SpecifiedLSList = $result.GetSpecifiedLicenseServerList().SpecifiedLSList  
                         LicensingType   = $result.LicensingType  
                         LicensingName   = $result.LicensingName   
                         ServerName      = $result.ServerName  
                         }  
                    }  
      
     (Get-ADGroupMember -Identity $ADGROUP).name |  
     Foreach-Object{   
         Try {   
             $result = Invoke-Command -ComputerName $_ -scriptblock $scriptblock -ErrorAction STOP | Format-Table -Property SpecifiedLSList, PSComputerName, LicensingName, LicensingType    
             # SilentlyContinue won't cause the "Catch" block to execute if Invoke-Command fails   
               
             #not working here, cant parse array object to build new one, with one header and datas        
             $outputobj = [PSCustomObject]@{  
             RDSserver = $result.PSComputerName  
             }  
      
             }   
             Catch{            
               
                # This will result in two lines of text being present in the midst of the results of the successful Invoke-Command outputs  
                # which will probably mess up the way they're displayed  
                #Write-Output "nError Message: " $_.Exception.Message  
                #Write-Output "`nError Item Name: " $_.Exception.ItemName  
                Write-Output "$($_) Error occured !"  
             }  
     }  
      
    $outputobj  
    
    0 comments No comments

  3. Rich Matheisen 47,596 Reputation points
    2022-06-15T01:41:41.607+00:00

    I only have a single machine to work with so I'm not sure what the contents of the object returned from the Invoke-Command will look like when you use the -Computer parameter. I know that PSComputerName is populated if more than one name is given as the value of -Computer, but I don't know if that's true only a single name is used.

    If this doesn't work, use Get-Member on the $result variable and report it here.

    $RDSADGROUP = "Remote_Desktop_Services"   
          
    $scriptblock = { $result = gwmi -Namespace "Root/CIMV2/TerminalServices" Win32_TerminalServiceSetting  
        [PSCustomObject]@{  
            ComputerName    = "Fill me in later"  
            SpecifiedLSList = $result.GetSpecifiedLicenseServerList().SpecifiedLSList  
            LicensingType   = $result.LicensingType  
            LicensingName   = $result.LicensingName   
            ServerName      = $result.ServerName  
        }  
    }  
          
    (Get-ADGroupMember -Identity $ADGROUP).name |  
        ForEach-Object {   
            Try {   
                $result = Invoke-Command -ComputerName $_ -ScriptBlock $scriptblock -ErrorAction STOP  
                $result.ComputerName = $_  
                $result  
            }   
            Catch {            
                   
                # This will result in two lines of text being present in the midst of the results of the successful Invoke-Command outputs  
                # which will probably mess up the way they're displayed  
                #Write-Output "nError Message: " $_.Exception.Message  
                #Write-Output "`nError Item Name: " $_.Exception.ItemName  
                Write-Output "$($_) Error occured !"  
            }  
        }  
    
    0 comments No comments

  4. Rich Matheisen 47,596 Reputation points
    2022-06-16T19:46:24.557+00:00

    I think that script can be simplified quite a bit. Was there a reason you chose to use Invoke-Command instead of just using Get-WMIObject directly?

    $computers = Get-ADGroupMember -Identity $ADGROUP  
    $computersnum = $computers.count    
    Write-Host "Number of machines found :  [$($computersnum)]" -ForegroundColor Green  
    $computers |  
        ForEach-Object{  
            $target = $_.Name  
            $result =   [PSCustomObject]@{  
                            ComputerName    = $_  
                            SpecifiedLSList = "n/a"  
                            LicensingType   = "n/a"  
                            LicensingName   = "n/a"  
                            ServerName      = "n/a"  
                            ErrorRecord     = ""  
                        }  
            $obj = Get-WmiObject -ComputerName $_ -namespace "Root/CIMV2/TerminalServices" Win32_TerminalServiceSetting 2>&1  
            if ($obj -is [ErrorRecord]){  
                  
                $result.ErrorRecord     = ""  
            }  
            else{  
                $result.SpecifiedLSList = $obj.GetSpecifiedLicenseServerList().SpecifiedLSList  
                $result.LicensingType   = $obj.LicensingType  
                $result.LicensingName   = $obj.LicensingName   
                $result.ServerName      = $obj.ServerName  
            }  
            $result  
        }
    
    0 comments No comments

  5. Brahms 1 Reputation point
    2022-06-15T16:50:21.137+00:00

    Hi sir,

    We're doing good progress and thank you very much ! I reviewed the code a bit and get almost what i want. But some servers are missing if there is any issue and the catch bloc is involved, i tried to create a new object and fill it, and then concatenate theses in a global one but it behaves weired. Maybe i have to rewrite the script by using if and else instead of try-catch scenario.

    Output :

    211726-output-script-rds.png

    Anyway here are the new results and the code :

    $RDSADGROUP = "Remote_Desktop_Services"   
              
     $scriptblock = { $result = gwmi -Namespace "Root/CIMV2/TerminalServices" Win32_TerminalServiceSetting  
         [PSCustomObject]@{  
             ComputerName    = $result.PSComputerName  
             SpecifiedLSList = $result.GetSpecifiedLicenseServerList().SpecifiedLSList  
             LicensingType   = $result.LicensingType  
             LicensingName   = $result.LicensingName   
             ServerName      = $result.ServerName  
         }  
     }  
      
     $outputobjfinal = @()  
     $computers = $null  
      
     $computers = Get-ADGroupMember -Identity $ADGROUP  
      
     $computersnum = $computers.count    
     Write-Host "Number of machines found :  [$($computersnum)]" -ForegroundColor Green     
       
     $computers.name |  
         ForEach-Object {   
             Try {   
                 $result = Invoke-Command -ComputerName $_ -ScriptBlock $scriptblock -ErrorAction STOP  
                 $result.ComputerName = $_  
                 $result  
      
                 $obj = [PSCustomObject]@{  
                         Computername    = $result.ComputerName  
                         ServerName      = $result.ComputerName # .GetSpecifiedLicenseServerList().SpecifiedLSList  
                         LicensingType   = $result.LicensingName # LicensingType  
                         LicensingName   = $result.LicensingType # LicensingName   
                         SpecifiedLSList = $result.SpecifiedLSList #ServerName  
                         }  
                $outputobjfinal += $obj  
      
             }   
             Catch {            
      
                 Write-Output "$($_) Error occured !"  
      
                 <# $obj2 = [PSCustomObject]@{  
                         Computername    = $_  
                         ServerName      = "n/a" # .GetSpecifiedLicenseServerList().SpecifiedLSList  
                         LicensingType   = "n/a" # LicensingType  
                         LicensingName   = "n/a" # LicensingName   
                         SpecifiedLSList = "n/a" #ServerName  
                         }  
      
                $outputobjfinal += $obj2 #>  
             }  
         }  
      
        Write-Output $outputobjfinal | Format-Table  
      
        $outputobjfinal.Count  
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.