Add Servers to Trusted Hosts

When using PowerShell remoting we often have to add the server(s) we wish to manage to our trusted hosts if our machine is not part of the same domain.  If you roam from site to site like I do then you’ll probably be adding them all the time.  Hence I am investigating and writing a tool that seeks out and finds servers on a given network, then adds them to trusted hosts for you.

OK, so lets begin.  In order to see a list of servers that are currently already added to your list you can use this command:

   1: Get-Item WSMan:\localhost\Client\TrustedHosts | select -ExpandProperty Value

This command will give you output of a single property, the ‘value’ property, which is the property that contains the server names, separated by a comma, that are already added to your trusted hosts list.  Its quite difficult to format this neatly as all entries are one value.  That aside there is one other command I think would be useful to note before we begin any tool making and that is the following:

   1: WinRM Set WinRM/Config/Client '@{TrustedHosts=""}'

Be careful when using the above command as this will clear all trusted hosts from your list but sometimes this can be useful in a test environment.

So, what is the task at hand?  Well I am going to write a tool that will add all servers on a domain to our trusted hosts list.  So how can we do this?  Well firstly we must add the domain  controller to our list.  Once the domain controller is in the list we should be able to pass a command to the domain controller to search AD for all other servers, and add them too.

So lets set up my script to ask for the domain name first of all.  To do this I will add a parameter to my tool so that when you call the script you will state the domain name and then it will prompt for credentials.  I will do this like so..

   1: param (
   2: [Parameter(Mandatory=$True)]
   3: [string]$Domain
   4: )
   5:  
   6: # Set Credential for connection
   7: $Credential = Get-Credential -Message "Please enter the credentials you have to connect to $Domain"

So the domain name is a mandatory parameter.  The script will not function without it.  Having the domain name will give us our basis for finding more information we need.

Next I will look to getting the domain information which we can do with the following command Get-ADDomain.  If you run that command, you will see all kinds of results returned but what I am after is the domain controller name.  The DC’s for the forest can be found under the property of ReplicaDirectoryServers.  Therefore if we run the command (Get-ADDomain).ReplicaDirectoryServers you will get a list of all domain controllers on the domain.  Now you could cycle through the list adding them to trusted hosts one at a time however you could just call the name of the first one in the list by adding [0] to the command to make (Get-ADDomain).ReplicaDirectoryServers[0].  Once we have one domain controller in we can query it for the other servers on the domain.

Running (Get-ADDomain).ReplicaDirectoryServers[0] should give you a FQDN of a domain controller on your domain.  GREAT!

Here is the line I used:

   1: $DomainController = (Get-ADDomain -Identity $Domain -Credential $Credential).ReplicaDirectoryServers[0]

$Domain is set when we call the script and $Credential is set by the (Get-Credential) command we ran earlier.  There is however one problem with the string that is contained within the variable $DomainController, it is a FQDN and we need the NETBIOS name of the machine to add to trusted hosts so we must split up the string.  As we all know a FQDN is split up by a dot (.), for example server01.domain.local.  We can use the .Split method to split up the string as such:

   1: $SplitDC = $DomainController.split('.')
   2: $NetBIOS = $SplitDC[0]

The $DomainController variable is split up by using the delimiter of “.” and each of the results are placed into an array into the variable $SplitDC.  To call the first entry in the variable we simply add the [0] we learned earlier and $NetBIOS becomes server01. Excellent!

Now we add this to trusted hosts before we can continue and add the rest of the servers on the domain.  We do this by using:

   1: Set-Item wsman:\localhost\Client\TrustedHosts -Value $NetBIOS -Concatenate -Force

Now we can connect to the DC and search for other servers on the domain.  We do that with an LDAP query using the Invoke-Command command like so:

   1: # Fetch other servers from DC
   2: $Servers = Invoke-Command -ComputerName $NetBIOS -Credential $Credential -script {
   3: import-module ActiveDirectory ;
   4: Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))"
   5: } #Close Scriptblock
   6:  
   7: $AllServers = $AllServers + $Servers.Name

This will use Invoke-Command to first import the activedirectory module (compatibility for older server operating systems that do not have automatic module loading) and then search AD for any computer objects where the operating system has the word ‘server’ in it.   This query however will return multiple properties about each computer object from AD.  We are only concerned about the Name property, hence that’s all we ask for.  I use $AllServers = $AllServers + $Servers.Name to convert the objects in the $Servers array to strings.  This is because the Set-Item commands’ parameter of –Value doesn’t accept objects.

After that the rest of the script is a simple ForEach command.  ForEach server in the array add to trusted hosts. 

   1: # Add other servers to trusted hosts
   2: ForEach ($Machine in $AllServers){
   3:  
   4:     Set-Item wsman:\localhost\Client\TrustedHosts -Value $Machine -Concatenate -Force
   5:             
   6:             # Write Verbose
   7:             Write-Verbose "$Machine - Added to Trusted Hosts"
   8:             
   9:                         } # Close ForEach

Easy.

Here is the completed Script i added in some verbose objects so if you call the script using something like this:

.\Set-TrustedHosts –Domain mydomain.local –verbose 

It will show you exactly what is did with verbose statements.

   1: <#
   2: Script to first add a domain controller to trusted hosts, then search AD and add the rest of the servers 
   3:  
   4: Author:  Jonathan of www.deploymentshare.com
   5: Version: 1.0.0
   6:  
   7: #>
   8:  
   9: param (
  10: [Parameter(Mandatory=$True)]
  11: [string]$Domain
  12: )
  13:  
  14: # Set Credential for connection
  15: $Credential = Get-Credential -Message "Please enter the credentials you have to connect to $Domain"
  16:  
  17: # Get Domain Controller
  18: $DomainController = (Get-ADDomain -Identity $Domain -Credential $Credential).ReplicaDirectoryServers[0]
  19: $SplitDC = $DomainController.split('.')
  20: $NetBIOS = $SplitDC[0]
  21:  
  22:         # Write Verbose
  23:     Write-Verbose "Domain Controller FQDN = $DomainController"
  24:     Write-Verbose "Domain Controller Short Name = $NetBIOS"
  25:  
  26: # Add DC to Trusted hosts
  27: Set-Item wsman:\localhost\Client\TrustedHosts -Value $NetBIOS -Concatenate -Force
  28:  
  29: # Fetch other servers from DC
  30: $Servers = Invoke-Command -ComputerName $NetBIOS -Credential $Credential -script {import-module ActiveDirectory ; Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))"}
  31: $AllServers = $AllServers + $Servers.Name
  32:  
  33: # Add other servers to trusted hosts
  34: ForEach ($Machine in $AllServers){
  35:  
  36:     Set-Item wsman:\localhost\Client\TrustedHosts -Value $Machine -Concatenate -Force
  37:             
  38:             # Write Verbose
  39:             Write-Verbose "$Machine - Added to Trusted Hosts"
  40:             
  41:                         } # Close ForEach
Hope this is useful to someone!

Jonathan

Add comment