Skip to content

Instantly share code, notes, and snippets.

@automationhaus
Last active December 15, 2016 14:49
Show Gist options
  • Save automationhaus/028d5b48c7c78d8189da931d3e2ff690 to your computer and use it in GitHub Desktop.
Save automationhaus/028d5b48c7c78d8189da931d3e2ff690 to your computer and use it in GitHub Desktop.
Saves and restores client printer default settings based on the locale of the client IP address. For use in logon/logoff scripts with users who float from site to site within an organization.
{
"Locales":{
"Datacenter":"10.11.16",
"Marietta":"10.0.1",
"Atlanta":"10.5.20"
}
}
function Set-SessionClientDefaultPrinter
{
<#
.Synopsis
Save RDS or Citrix client default printer based on location
.DESCRIPTION
Saves the currently selected default to printer to a storage key and restores that default printer based on location. For use as a logon / logoff script.
.PARAMETER Locales
Hashtable of location names and IP blocks that describe the location
.PARAMETER Save
Switch to enable saving the default printer details to the destination storage key
.PARAMETER Log
Switch to enable logging to CSV
.EXAMPLE
Save the default printer settings with logging - best used as a logoff script
PS>.\Set-SessionClientDefaultPrinter -Locales @{"ATL"="10.0.0";"NYC"="10.1.0"} -Save -Log
.EXAMPLE
Restore the printer settings using locales defined in the Config.json file - best used as a logon script
PS>.\Set-SessionClientDefaultPrinter
.NOTES
You have the option to use a config.json file for the locales to establish the array of values that will be converted to a hashtable
Britt Thompson
[email protected]
.LINK
https://gist.github.com/amesritter/028d5b48c7c78d8189da931d3e2ff690
#>
[CmdletBinding(SupportsShouldProcess=$true)]
Param
(
[System.Collections.Hashtable]$Locales,
[switch]$Save,
[switch]$Log,
[String]$StorageKey="Customer"
)
Begin
{
#region FUNCTIONS
function ConvertTo-HashTable($Obj)
{
# Basic function to convert the custom object from the JSON file to a hashtable
$H = @{}
foreach($X in $Obj.PSObject.Properties){ $H.Add($X.Name,$X.Value) }
$H
}
function Get-Catch { Write-Host $_.Exception.Message -ForegroundColor Red }
function Get-RDSCurrentSession
{
<#
.SYNOPSIS
Provides information about the current logged in session on the session host
.DESCRIPTION
Using Cassia .NET Library gathers information on the current logged in user/client on the local session host
.EXAMPLE
PS>Get-RDSCurrentSession
.OUTPUTS
Cassia.Impl.TerminalServicesSession
.NOTES
Britt Thompson
[email protected]
.LINK
http://code.google.com/p/cassia/
.LINK
https://gist.github.com/amesritter/766fa2c1941f0093243440971424cbce
#>
[OutputType("Cassia.Impl.TerminalServicesSession")]
[CmdletBinding()]
param()
try
{
Add-Type -Path "$PSScriptRoot\Bin\Cassia.dll"
$RDSClient = New-Object Cassia.TerminalServicesManager
$RDSClient.CurrentSession
} catch { Get-Catch }
}
#endregion
#region VARS
$ErrorActionPreference = "Stop"
# Establish script path for log output
$ScriptPath = $PSScriptRoot
[string]$DateFormat = Get-Date -Format yyyy-MM-dd
$LogPath = "$ScriptPath\Logs"
$LogFile = "$LogPath\PrinterDefaults_$DateFormat.csv"
# Establish the registry storage path for the saved printer settings
$StoragePath = "HKCU:\Software\$StorageKey"
# If the config file is available import the variables
if(Test-Path "$ScriptPath\Config.json")
{
$Vars = (Get-Content -Raw "$ScriptPath\Config.json") | ConvertFrom-Json
}
# Check for the Locales parameter and config file locales. Convert config file locales to a hashtable
if(-not $Locales -and $Vars.Locales){ $Locales = ConvertTo-HashTable $Vars.Locales }
# Get the current client info
try { $Client = Get-RDSCurrentSession } catch { Get-Catch }
#endregion
}
Process
{
if ($PSCmdlet.ShouldProcess($Locales))
{
# Create the logs directory if it doesn't exist
if(-not (Test-Path "$ScriptPath\Logs"))
{
$LogsDir = New-Item -Path "$ScriptPath\Logs" -ItemType Directory
}
# Check for locales and the reg key storage path
if(-not $Locales){ Write-Host "No locales configured" -ForegroundColor Red; break }
if (-not (Test-Path $StoragePath)) { try { $SK = New-Item -Path $StoragePath } catch { Get-Catch } }
# Default printer settings key
$Defaults = "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows"
# Check each locale IP address block against the current client IP and set the current locale
if($Client.ClientIPAddress.IPAddressToString)
{
foreach($L in $Locales.GetEnumerator().Name)
{
if($Client.ClientIPAddress.IPAddressToString -match $Locales.$L){ $Locale = $L }
}
}
# If no locales were matched then set the locale as remote
if(-not $Locale){ $Locale = "Remote" }
# Set a generic variable for the locale key
$Key = "$StoragePath\$Locale"
# Configure save and restore source and destination
if($Save){ $Src = $Defaults; $Dst = $Key } else { $Src = $Key; $Dst = $Defaults }
# If the storage key doesn't exist create it
if(-not (Test-Path $Key))
{
try { $PSK = New-Item -Path $Key; Write-Verbose "Created: $Key" } catch { Get-Catch }
}
try
{
# Get the current saved or default printer settings
$Printer = Get-ItemProperty -Path $Src -Name Device | %{ $_.Device }
# Restore or save the default printer
if($Printer){ $NIP = New-ItemProperty -Path $Dst -Name Device -PropertyType String -Value $Printer -Force }
} catch { Get-Catch }
if($Save){ $Method = "Save" } else { $Method = "Restore" }
Write-Verbose "ClientName: $($Client.ClientName)"
Write-Verbose "SessionID: $($Client.SessionID)"
Write-Verbose "IPAddress: $($Client.ClientIPAddress.IPAddressToString)"
Write-Verbose "User: $($Client.UserName)"
Write-Verbose "Server: $($Client.Server.ServerName)"
Write-Verbose "Locale: $Locale"
Write-Verbose "Method: $Method"
# If logging is enabled send the client data output to CSV
if($Log)
{
try
{
# Add the custom object locale client object
$Client | Add-Member -MemberType NoteProperty -Name Locale -Value $Locale
$Client | Add-Member -MemberType NoteProperty -Name Method -Value $Method
# Export the client object to CSV with append
$Client | Select *,@{Name="ServerName"; Expression = {$_.Server.ServerName}} |
Export-CSV -Path $LogFile -Append -NoTypeInformation -Force
} catch { Get-Catch }
}
}
}
}
@automationhaus
Copy link
Author

The JSON configuration file is optional and included as an example. If you have a huge number sites it would be too cumbersome to pass the hashtable as a parameter. Managing an external file is a good deal simpler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment