优化脚本以创建 Citrix 场策略 运行 太慢

Optimizing script to create Citrix farm policies is running too slow

在社区的帮助下,我终于完成了一个基本脚本,它将创建工作组、策略、策略设置,然后 link 工作组的策略。

我有很多 write-hosts 只是为了看看发生了什么,看看脚本在哪里最有效,将被删除。

当它设置 set-ctxgrouppolicyconfiguration 设置时,它很慢。该脚本大约需要 8-10 分钟才能完成,速度非常慢。将每个策略手动写入 SQL 后端时,Citrix 应用程序中心本身就很慢,因此不确定是否可以加快速度。

import-module Citrix.GroupPolicy.Commands 
add-pssnapin *Citrix* 

$count = 0
$tomorrow = ConvertTo-DwordDate -date (get-date).AddDays(1)
new-xafolder 'WorkerGroups/reboot schedules'

$days = @("mon", "tues", "wed", "thurs", "fri", "sat", "sun")
foreach ($day in $days) {
    write-host "processing $day"
    $count = $count + 1

    write-host "creating workerGroup"
    new-xaworkergroup "$day - 3am" -folderpath 'WorkerGroups/reboot schedules' -description "scheduled reboot for $day - 3am"

    write-host "creating policy"
    new-ctxgrouppolicy "reboot $day 3am" -type computer -priority $count

    write-host "linking policy to workerGroup"
    add-ctxgrouppolicyfilter "reboot $day 3am" computer servergroup0 workergroup "$day - 3am"

    write-host "setting reboot parameters"
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer scheduledReboots enabled
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootWarningMessage enabled
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootWarningStartTime enabled  -value start60MinutesBeforeReboot
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootWarningInterval enabled   -value every10Minutes
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootScheduleTime enabled      -value 180
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootScheduleFrequency enabled  -value 7
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootDisableLogOnTime enabled   -value disable15MinutesBeforeReboot
    set-ctxgrouppolicyconfiguration "reboot $day 3am" computer rebootScheduleStartDate enabled  -value $tomorrow
}
$count = $count + 1
set-ctxgrouppolicy -policyname unfiltered -type computer -priority $count

write-host "script complete"

#------------------------------
#functions for date conversion
#------------------------------

function convertFrom-DwordDate([int32]$DwordValue){
    #ex. $DwordValue = 132055314
    #convert to hex
    $hex = $DwordValue.ToString('X8')
    #$Ex. $hex = 0x07df0112 = 0x07df (year) 0x01(month) 0x12 (day)

    #Convert to date string
    $datestring = '{0:D4}\{1:D2}\{2:D2}' -f [convert]::ToUInt32($hex.Substring(0,4),16), [convert]::ToUint32($hex.Substring(4,2),16), [convert]::ToUInt32($hex.Substring(6,2),16)
    #convert to datetime and output
    $datetime = [datetime]::ParseExact($datestring,'yyyy\MM\dd',$null)
    #output
    $datetime
}

function ConvertTo-DwordDate([datetime]$Date) {
    #convert to combined hex
    $combinedhex = '{0:X}{1:X2}{2:X2}' -f $Date.Year, $Date.Month, $Date.Day
    #convert to decimal
    $decimal = [convert]::ToUInt32($combinedhex,16)
    #output
    $decimal
}

我不熟悉 Citrix SDK,但查看 this site,您似乎可以将整个策略作为对象接收。我建议这样做,这样您就可以在本地修改它,并且只在循环中每个 "day" 结束时保存 GPO 一次。这会将 8 个保存调用替换为 1 个。像这样:

注意:未经测试!通读并首先在测试环境中尝试。如前所述,我没有使用过此模块的经验,因此无法保证它会按预期工作或根本无法工作。您可能还想先手动尝试 运行 命令而不是整个循环,以尽量减少可能的 "damage".

import-module Citrix.GroupPolicy.Commands 
add-pssnapin *Citrix* 

$count = 0
$tomorrow = ConvertTo-DwordDate -date (get-date).AddDays(1)
new-xafolder 'WorkerGroups/reboot schedules'

#Not sure if needed or if you could remove this and -DriveName CitrixGPO commands later
#Add PowerShell snapins (if necessary)
if ( (Get-PSSnapin -Name Citrix.Common.GroupPolicy -ErrorAction SilentlyContinue) -eq $null ) { Add-PSSnapin Citrix.Common.GroupPolicy }
if ( (Get-PSSnapin -Name Citrix.Common.Commands -ErrorAction SilentlyContinue) -eq $null ) { Add-PSSnapin Citrix.Common.Commands }
if ( (Get-PSSnapin -Name Citrix.XenApp.Commands -ErrorAction SilentlyContinue) -eq $null ) { Add-PSSnapin Citrix.XenApp.Commands }
New-PSDrive -Name CitrixGPO -PSProvider CitrixGroupPolicy -Root \ -DomainGPO "Citrix GPO"
#END "not sure if needed"


$days = @("mon", "tues", "wed", "thurs", "fri", "sat", "sun")
foreach ($day in $days) {
    write-host "processing $day"
    $count = $count + 1

    write-host "creating workerGroup"
    new-xaworkergroup "$day - 3am" -folderpath 'WorkerGroups/reboot schedules' -description "scheduled reboot for $day - 3am"

    write-host "creating policy"
    new-ctxgrouppolicy "reboot $day 3am" -type computer -priority $count

    write-host "linking policy to workerGroup"
    add-ctxgrouppolicyfilter "reboot $day 3am" computer servergroup0 workergroup "$day - 3am"

    write-host "getting policy"
    $objCitrixPolicy = Get-CtxGroupPolicyConfiguration -PolicyName "reboot $day 3am" -Type compuer -DriveName CitrixGPO #-DriveName CitrixGPO might not be needed

    write-host "modifying policy"
    $objCitrixPolicy.("scheduledReboots").State = "Enabled"

    $objCitrixPolicy.("rebootWarningMessage").State = "Enabled"

    $objCitrixPolicy.("rebootWarningStartTime").State = "Enabled"
    $objCitrixPolicy.("rebootWarningStartTime").Value = "start60MinutesBeforeReboot"

    $objCitrixPolicy.("rebootWarningInterval").State = "Enabled"
    $objCitrixPolicy.("rebootWarningInterval").Value = "every10Minutes"

    $objCitrixPolicy.("rebootScheduleTime").State = "Enabled"
    $objCitrixPolicy.("rebootScheduleTime").Value = 180

    $objCitrixPolicy.("rebootScheduleFrequency").State = "Enabled"
    $objCitrixPolicy.("rebootScheduleFrequency").Value = 7

    $objCitrixPolicy.("rebootDisableLogOnTime").State = "Enabled"
    $objCitrixPolicy.("rebootDisableLogOnTime").Value = "disable15MinutesBeforeReboot"

    $objCitrixPolicy.("rebootScheduleStartDate").State = "Enabled"
    $objCitrixPolicy.("rebootScheduleStartDate").Value = $tomorrow

    write-host "saving policy"
    Set-CtxGroupPolicyConfiguration $objCitrixPolicy -DriveName CitrixGPO #-DriveName CitrixGPO might not be needed

}
$count = $count + 1
set-ctxgrouppolicy -policyname unfiltered -type computer -priority $count

#Close PowerShell Drive from Citrix domain GPO
Remove-PSDrive -Name CitrixGPO

write-host "script complete"

#------------------------------
#functions for date conversion
#------------------------------

function convertFrom-DwordDate([int32]$DwordValue){
    #ex. $DwordValue = 132055314
    #convert to hex
    $hex = $DwordValue.ToString('X8')
    #$Ex. $hex = 0x07df0112 = 0x07df (year) 0x01(month) 0x12 (day)

    #Convert to date string
    $datestring = '{0:D4}\{1:D2}\{2:D2}' -f [convert]::ToUInt32($hex.Substring(0,4),16), [convert]::ToUint32($hex.Substring(4,2),16), [convert]::ToUInt32($hex.Substring(6,2),16)
    #convert to datetime and output
    $datetime = [datetime]::ParseExact($datestring,'yyyy\MM\dd',$null)
    #output
    $datetime
}

function ConvertTo-DwordDate([datetime]$Date) {
    #convert to combined hex
    $combinedhex = '{0:X}{1:X2}{2:X2}' -f $Date.Year, $Date.Month, $Date.Day
    #convert to decimal
    $decimal = [convert]::ToUInt32($combinedhex,16)
    #output
    $decimal
}