Optimizing Provisioning Services with Powershell

When you’re deploying lots of systems, anything that can make the deployment more efficient is always welcome – so basically, any automation is always welcome.

These scripts I use on both PVS servers and targets – the first script disables all network offloads on the VMXNET3 adapter and the second sets up the persistent data on the writecache volume (obviously the 2nd is only for targets).

Here’s the first – this is specific to PVS server\target running on VMware with VMXNET3 network adapters:

[code language=”powershell”]
# Citrix Provisioning Server target device network optimizer
# Author: Jacob Rutski
# @JRutski on Twitter; blogs.serioustek.net
# Use this script at your own risk!
# I am not responsible for any harm or misconfiguration done by this script
#———————————————————————————–
# Writes to the registry after checking if key path exists
# Acceptable Registry types: Binary, DWord, ExpandString, MultiString, String, QWord
# Ex: RegWrite HKCU:\Software\Policies\Microsoft\Windows "IETabs" 1 DWord
Function RegWrite ($regPath, $regName, $regValue, $regType)
{
    If (!(Test-Path $regPath))
    {
        New-Item -Path $regPath -force
    }
    New-ItemProperty $RegPath -Name $regName -Value $regValue -PropertyType $regType -force
}
#—————————-
# Disable offloads globally
#—————————-
RegWrite "HKLM:\System\CurrentControlSet\Services\TCPIP\Parameters\DisableTaskOffload" 1 DWord
#—————————-
# Disable all IPv6 in registry
#—————————-
RegWrite "HKLM:\SYSTEM\CurrentControlSet\Services\TCPIP6\Parameters" "DisabledComponents" 0x000000FF Dword
#—————————-
# Disable all offloads for VMXNET3 adapters
#—————————-
Get-ChildItem ‘HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}’ -rec -ea SilentlyContinue | foreach {
   $CurrentKey = (Get-ItemProperty -Path $_.PsPath)
   If ($CurrentKey -match "vmxnet3 Ethernet Adapter")
   {
    $StrKeyPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\" + $CurrentKey.PSPath.Substring($CurrentKey.PSPath.Length – 4, 4)
    RegWrite $StrKeyPath "*IPChecksumOffloadIPv4" 0 String
    RegWrite $StrKeyPath "*TCPChecksumOffloadIPv4" 0 String
    RegWrite $StrKeyPath "*UDPChecksumOffloadIPv4" 0 String
    RegWrite $StrKeyPath "*LsoV1IPv4" 0 String
    RegWrite $StrKeyPath "*LsoV2IPv4" 0 String
    RegWrite $StrKeyPath "OffloadIPOptions" 0 String
    RegWrite $StrKeyPath "OffloadTcpOptions" 0 String
    
    }
  }
[/code]

The second script sets up persistent data on the writecache volume – move and create a 4GB page file, event logs and print spooler. The idea with this script is to add a non-formatted disk to the target then run the script – it will find the disk, format it and assign a drive letter, then do all of the persistent stuff.

[code language=”powershell”]
# Citrix Provisioning Server target device persistent volume setup
# Author: Jacob Rutski
# @JRutski on Twitter; blogs.serioustek.net
# Use this script at your own risk!
# I am not responsible for any harm or misconfiguration done by this script
#———————————————————————————–
# Writes to the registry after checking if key path exists
# Acceptable Registry types: Binary, DWord, ExpandString, MultiString, String, QWord
# Ex: RegWrite HKCU:\Software\Policies\Microsoft\Windows "IETabs" 1 DWord
Function RegWrite ($regPath, $regName, $regValue, $regType)
{
    If (!(Test-Path $regPath))
    {
        New-Item -Path $regPath -force
    }
    New-ItemProperty $RegPath -Name $regName -Value $regValue -PropertyType $regType -force
}
#—————————-
# Move CD Drive to E: and init 2nd volume
#—————————-
# Find drives with no partitions
$getInitDrive = gwmi -Query "Select * from Win32_diskdrive where Partitions = 0"
If (!$getInitDrive)
{
    Exit
}
# Get CDROM drive, move drive letter to E:
$getDrive = gwmi -query "Select DeviceID from Win32_LogicalDisk Where DriveType=5"
$cdDrive = gwmi Win32_Volume -filter "DriveLetter=’$($getDrive.DeviceId)’"
$cdDrive.DriveLetter=’E:’
$cdDrive.Put()
# Init drive
$newDisk = $getInitDrive.DeviceID.Replace("\\.\PHYSICALDRIVE", "")
$DPCommands = @"
select disk $newDisk
online disk noerr
attribute disk clear readonly
create partition primary
format fs=ntfs label=WriteCache quick
assign letter D:
"@
$DPCommands | diskpart
#—————————-
# Create folder structure for persistent data
#—————————-
New-Item -ItemType Directory -Path D:\Persist
New-Item -ItemType Directory -Path D:\Persist\EventLogs
New-Item -ItemType Directory -Path D:\Persist\spool
New-Item -ItemType Directory -Path D:\Persist\spool\PRINTERS
#—————————-
# Set pagefile
#—————————-
$PageSystem = GWMI Win32_ComputerSystem -EnableAllPrivileges
$PageSystem.AutomaticManagedPagefile = $False
$PageSystem.Put()
$CurrentPageFile = GWMI -Query "Select * from Win32_PageFileSetting where name=’c:\\pagefile.sys’"
$CurrentPageFile.Delete()
Set-WmiInstance -Class Win32_PageFileSetting -Arguments @{name="d:\pagefile.sys";InitialSize = 4096;MaximumSize = 4096}
#—————————-
# Set spooler directory
#—————————-
RegWrite HKLM:\SYSTEM\CurrentControlSet\Control\Print\Printers "DefaultSpoolDirectory" "D:\Persist\spool\PRINTERS" String
#—————————-
# Move Event logs
#—————————-
IEX "wevtutil sl System /lfn:D:\Persist\EventLogs\System.evtx"
IEX "wevtutil sl Application /lfn:D:\Persist\EventLogs\Application.evtx"
IEX "wevtutil sl Security /lfn:D:\Persist\EventLogs\Security.evtx"
#—————————-
# Reboot
#—————————-
Restart-Computer

[/code]
Please note that both of these scripts will need to be run with administrative privileges. Happy scripting and please post any issues or comments.

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.