Greetings!!
I dont know about you, but we have had some HUGE proplems with HP printers and its universal drivers the last year. Administering some 500+ HP Printers this means ALOT of time spend on trouble shooting and fixing problems.
The latest issue is the some printers suddently use Raster graphics instead of Vector graphics which means that the time it takes to print a document increases from a few seconds to several minutes, plus a 100kb document infaltes to a 1gb document!!
Unfortunatly this setting is being set into a registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers\SY101P01\Default Devmode. This registry key contains several settings and is unique for each printer. It is not an option to hardcode anything into this key in this scenario.
I found that when a printer gets the raster setting, the registry key contains the following sequence: "82 65 83 84 69 82 77 79 68 69".
I saw no other option to make a backup of det default Devmode for each printer when it was in a good condition.
The following script checks if a printer graphics mode is Raster and if it is the replace the dirty regkey with a healty one.
Function SetDevModeToVector($printer,$printerRegKey)
{
if(Test-Path ("c:\Mandatory\Print\devmode\$printer"+".txt"))
{
Write-Host "Restoring Registry"
$strdevMode=Get-Content ("c:\Mandatory\Print\devmode\$printer"+".txt")
# We need to convert the data into an array of [byte]
[Byte[]]$devModeAry = $strdevmode.split(" ")
#Write the data into the registry on the remote machine
$printerRegKey.setvalue("Default Devmode",$devModeAry,"BINARY")
Write-Host "Done restoring Registry"
}
ELSE
{
Write-Host ("c:\Mandatory\Print\devmode\$printer"+".txt") + "not found"
}
}
$fileout = "c:\filnavn.txt"
$fileObj = New-Item -ItemType file $fileout -Force
#Export Printer Dev Mode Settings
$ErrorActionPreference = "silentlycontinue"
$RasterSequenceDEC = "82 65 83 84 69 82 77 79 68 69"
[string]$strByte = ""
$computers=Get-CTX5PrintServers SY $args | %{$_.properties.name}
#$computers = "B3562S99"
foreach($computer in $computers)
{
Write-Host "Processing $computer"
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $computer)
$regKey = $reg.OpenSubKey("Software\Microsoft\windows nt\CurrentVersion\Print\printers",$true)
$printers = $regKey.GetSubKeyNames()
[Boolean]$restartSpooler=$false
foreach($printer in $printers)
{
$PrinterRegKey= $reg.OpenSubKey("Software\Microsoft\windows nt\CurrentVersion\Print\printers\$printer",$true)
$devModeAry = $PrinterRegKey.GetValue("Default DevMode")
foreach($byt in $devModeAry)
{
[string]$strByte = $strByte +" "+ $byt
}
$strByte = $strByte.substring(1)
if($strByte -match $RasterSequenceDEC)
{
$restartSpooler=$true
Write-Host -ForegroundColor Yellow "Found raster on printer $printer on $computer"
$tekst="Found raster on printer $printer on $computer"
Add-Content $fileObj $tekst
SetDevModeToVector $printer $PrinterRegKey
}
ELSE
{
$strByte | Out-File c:\Mandatory\Print\DevMode\$printer.txt
}
$strByte=$null
$PrinterRegKey.Close()
}
$regKey.close()
$reg.close()
if($restartSpooler -eq $true)
{
Restart-RemoteService -computer $computer -service Spooler
}
}
This script contains a costumiced commandlet; Restart-RemoteService. This commandlets are a part of a module i wrote, which is loaded on every server in the forest.
Restart-Remoteservice takes a service and a computer as input and will restart the given service on the given computer. Easy and simple, not very elegant, but it gets the job done :)
CSO Powershell Blog
Blogging daily challenges as an IT Pro, and how they are fixed with Powershell.
1. december 2011
30. november 2011
Start, stop and restart services on remote machines
Greetings!
I would like to share a couple of nifty commandlets that i build into out costume module.
Start-RemoteService, Stop-RemoteService and Restart-RemoteService.
This is particular nice when PrintServer104 is troubeling you and you need to restart spooler. Easy task, but normally you would either log onto the server and fire up whatever favorite way to stop a service or on a remote server start services.msc and remote connect to a the printserver, find the service and restart it.
With these commandlets it have become faster and easier. In your favorite prompt (assuming that is a Powershell prompt) type
Restart-RemoteService -computer PrintServer104 -service spooler
You can also just choose to start a searvice by
Start-RemoteService -computer PrintServer104 -service spooler
or stop a service by
Stop-RemoteService -computer PrintServer104 -service spooler
Cut and past these functions into your custom module and save time and frustrations by getting the job done :)
Function Start-RemoteService
{
<#
.Synopsis
Send a command to remote server to start a specifik service
.Description
Send a command to remote server to start a specifik service
.Parameter $Computer
Computername
.Parameter $service
Service to restart
.Example
Start-RemoteService Server01 spoolsv
Description
-----------
Will start the service named spoolsv on server Server01
.Notes
NAME: Start-RemoteService
AUTHOR: Claus Søgaard
#>
[CmdletBinding()]
param([string]$strComputer,[String]$strService)
Process
{
$result=(Get-WmiObject -computer $strComputer Win32_Service -Filter "Name='$strService'").InvokeMethod("startService",$null)
if($result -eq "0")
{
Write-Host "Succesfully started $strService"
}
ELSE
{
Write-Host -ForegroundColor Red "Failed to start $service on $strComputer"
}
}
}
Function Stop-RemoteService
{
<#
.Synopsis
Send a command to remote server to stop a specifik service
.Description
Send a command to remote server to stop a specifik service
.Parameter $Computer
Computername
.Parameter $service
Service to stop
.Example
Stop-RemoteService Server01 spoolsv
Description
-----------
Will stop the service named spoolsv on server Server01
.Notes
NAME: Stop-RemoteService
AUTHOR: Claus Søgaard
#>
[CmdletBinding()]
param([string]$strComputer,[String]$strService)
Process
{
$result=(Get-WmiObject -computer $strComputer Win32_Service -Filter "Name='$strService'").InvokeMethod("stopService",$null)
if($result -eq "0")
{
Write-Host "Succesfully stopped $service on $strComputer"
}
ELSE
{
Write-Host -ForegroundColor Red "Failed in stopping $strService"
}
}
}
Function Restart-RemoteService
{
<#
.Synopsis
Send a command to remote server to restart a specifik service
.Description
Send a command to remote server to restart a specifik service
.Parameter $Computer
Computername
.Parameter $service
Service to restart
.Example
Restart-RemoteService Server01 spoolsv
Description
-----------
Will restart the service named spoolsv on server Server01
.Notes
NAME: Start-RemoteService
AUTHOR: Claus Søgaard
#>
[CmdletBinding()]
param([Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][string]$Computer,
[Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][String]$service)
Process
{
Stop-RemoteService $computer $service
Start-Sleep 1
Start-RemoteService $computer $service
}
}
I would like to share a couple of nifty commandlets that i build into out costume module.
Start-RemoteService, Stop-RemoteService and Restart-RemoteService.
This is particular nice when PrintServer104 is troubeling you and you need to restart spooler. Easy task, but normally you would either log onto the server and fire up whatever favorite way to stop a service or on a remote server start services.msc and remote connect to a the printserver, find the service and restart it.
With these commandlets it have become faster and easier. In your favorite prompt (assuming that is a Powershell prompt) type
Restart-RemoteService -computer PrintServer104 -service spooler
You can also just choose to start a searvice by
Start-RemoteService -computer PrintServer104 -service spooler
or stop a service by
Stop-RemoteService -computer PrintServer104 -service spooler
Cut and past these functions into your custom module and save time and frustrations by getting the job done :)
Function Start-RemoteService
{
<#
.Synopsis
Send a command to remote server to start a specifik service
.Description
Send a command to remote server to start a specifik service
.Parameter $Computer
Computername
.Parameter $service
Service to restart
.Example
Start-RemoteService Server01 spoolsv
Description
-----------
Will start the service named spoolsv on server Server01
.Notes
NAME: Start-RemoteService
AUTHOR: Claus Søgaard
#>
[CmdletBinding()]
param([string]$strComputer,[String]$strService)
Process
{
$result=(Get-WmiObject -computer $strComputer Win32_Service -Filter "Name='$strService'").InvokeMethod("startService",$null)
if($result -eq "0")
{
Write-Host "Succesfully started $strService"
}
ELSE
{
Write-Host -ForegroundColor Red "Failed to start $service on $strComputer"
}
}
}
Function Stop-RemoteService
{
<#
.Synopsis
Send a command to remote server to stop a specifik service
.Description
Send a command to remote server to stop a specifik service
.Parameter $Computer
Computername
.Parameter $service
Service to stop
.Example
Stop-RemoteService Server01 spoolsv
Description
-----------
Will stop the service named spoolsv on server Server01
.Notes
NAME: Stop-RemoteService
AUTHOR: Claus Søgaard
#>
[CmdletBinding()]
param([string]$strComputer,[String]$strService)
Process
{
$result=(Get-WmiObject -computer $strComputer Win32_Service -Filter "Name='$strService'").InvokeMethod("stopService",$null)
if($result -eq "0")
{
Write-Host "Succesfully stopped $service on $strComputer"
}
ELSE
{
Write-Host -ForegroundColor Red "Failed in stopping $strService"
}
}
}
Function Restart-RemoteService
{
<#
.Synopsis
Send a command to remote server to restart a specifik service
.Description
Send a command to remote server to restart a specifik service
.Parameter $Computer
Computername
.Parameter $service
Service to restart
.Example
Restart-RemoteService Server01 spoolsv
Description
-----------
Will restart the service named spoolsv on server Server01
.Notes
NAME: Start-RemoteService
AUTHOR: Claus Søgaard
#>
[CmdletBinding()]
param([Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][string]$Computer,
[Parameter(Position=1,Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][String]$service)
Process
{
Stop-RemoteService $computer $service
Start-Sleep 1
Start-RemoteService $computer $service
}
}
24. november 2011
Delete cookies
Hello,
Just had a user calling me telling me that on a specific site where the user needs to log in and specify a location to where his documents are, it shows an invalid path to the old fileserver.
Ruling out any GPO, i turned to cookies. Since we never delete any cookies for the users, this one have had thousands og cookies!
I want to find cookies where this site have saved som informations and i just need the job done...
declaring the path to cookies (which is on a fileserver)
$path=\\Fileserver\svprofil$\System\SVJVI\Citrix\H5\cookies
Now get all the cookies
$cookies=Get-ChildItem $path
now find the cookies that contains the specific site$matchCookies=$cookies | Select-String -Pattern "<specific site>"
$matchCookies | gm reveals that
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RelativePath Method string RelativePath(string directory)
ToString Method string ToString(), string ToString(string directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property System.String Filename {get;}
IgnoreCase Property System.Boolean IgnoreCase {get;set;}
Line Property System.String Line {get;set;}
LineNumber Property System.Int32 LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property System.String Path {get;set;}
Pattern Property System.String Pattern {get;set;}
in order to remove a file we need the entire path. We dont have fullname in out members, but we do have filename. I use the path from before and melt it with the attribute filename.
$cookies | Select-String -Pattern "danskebank" | foreach{"$path\"+$_.filename}
file://fileserver/profileShare$/System/Username/Citrix/H/cookies/BJ9NTMU2.txt
file://fileserver/svprofil$/System/SVJVI/Citrix/H/cookies/MFBOIQR5.txt
file://fileserver/svprofil$/System/SVJVI/Citrix/H/cookies/8VN8Y5A5.txt
now its just to implement remove-item:
$cookies | Select-String -Pattern "danskebank" | foreach{remove-item ("$path\"+$_.filename)}
jobs done :)
Just had a user calling me telling me that on a specific site where the user needs to log in and specify a location to where his documents are, it shows an invalid path to the old fileserver.
Ruling out any GPO, i turned to cookies. Since we never delete any cookies for the users, this one have had thousands og cookies!
I want to find cookies where this site have saved som informations and i just need the job done...
declaring the path to cookies (which is on a fileserver)
$path=\\Fileserver\svprofil$\System\SVJVI\Citrix\H5\cookies
Now get all the cookies
$cookies=Get-ChildItem $path
now find the cookies that contains the specific site$matchCookies=$cookies | Select-String -Pattern "<specific site>"
$matchCookies | gm reveals that
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RelativePath Method string RelativePath(string directory)
ToString Method string ToString(), string ToString(string directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property System.String Filename {get;}
IgnoreCase Property System.Boolean IgnoreCase {get;set;}
Line Property System.String Line {get;set;}
LineNumber Property System.Int32 LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property System.String Path {get;set;}
Pattern Property System.String Pattern {get;set;}
in order to remove a file we need the entire path. We dont have fullname in out members, but we do have filename. I use the path from before and melt it with the attribute filename.
$cookies | Select-String -Pattern "danskebank" | foreach{"$path\"+$_.filename}
file://fileserver/profileShare$/System/Username/Citrix/H/cookies/BJ9NTMU2.txt
file://fileserver/svprofil$/System/SVJVI/Citrix/H/cookies/MFBOIQR5.txt
file://fileserver/svprofil$/System/SVJVI/Citrix/H/cookies/8VN8Y5A5.txt
now its just to implement remove-item:
$cookies | Select-String -Pattern "danskebank" | foreach{remove-item ("$path\"+$_.filename)}
jobs done :)
Fixing users UserPrincipalName
We have had a scenario where some users lacked the attribute UserPrincipalName.
To find these users I used:
To find these users I used:
$users=Get-ADUser -Server <DomainController> -filter * -searchbase "OU=Users,OU=Hosting,DC=<subdomain>,DC=<rootDomain>,DC=dk" | where {$_.userPrincipalName -eq $null}
Now to fix the attribute:
$users | foreach{$_.samaccountname;$_.UserPrincipalName = ($_.samaccountname+"@subdomain.rootdomain.dk");set-aduser -instance $_}
You can question the readability of this, but it gets the job done which is what we want.
Best regards
Claus
Best regards
Claus
Abonner på:
Opslag (Atom)