最近我们开始在PowerShell中探索Workflows。它大大提高了执行速度,但它也增加了额外的复杂性。
以下代码存在范围问题。 Parallel
子句($Workflow:Ports
和$Workflow:Drivers
)中的变量显然分布在不同的$ComputerNames
上,而不是特定于一个$ConputerName
。检查technet时,我似乎无法弄清楚如何使变量$Ports
和$Drivers
特定于该计算机($C
)。
使用$Workflow:Ports
时,它们在所有计算机之间共享,这不是我们想要的。使用$Ports
时,InlineScript
子句中没有{。}}。
代码:
Workflow Get-PrintersInstalledHC {
Param (
[String[]]$ComputerName
)
Foreach -Parallel ($S in $ComputerName) {
$Computer = InlineScript {
[PSCustomObject]@{
ComputerName = $Using:S
ComputerStatus = $null
Printers = $null
RetrievalDate = Get-Date
}
}
# $VerbosePreference = [System.Management.Automation.ActionPreference]$Using:VerbosePreference
Try {
$Printers = Get-Printer -ComputerName $S -Full -EA Stop
if ($Printers) {
Write-Verbose "$S Found $($Printers.Count) printers"
Parallel {
$Workflow:Ports = Get-PrinterPort -ComputerName $S
$Workflow:Drivers = Get-PrinterDriver -ComputerName $S
}
$CimConfig = InlineScript {
Try {
#region CmdLets that require admin permissions
$Params = @{
ComputerName = $Using:S
ClassName = 'Win32_PrinterConfiguration'
Property = '*'
ErrorAction = 'Stop'
Verbose = $false
}
$Config = Get-CimInstance @Params
Foreach ($P in $Using:Printers) {
Foreach($C in $Config) {
if ($P.Name -eq $C.Name) {
@{
PrinterName = $P.Name
CimStatus = 'Ok'
DriverVersionCim = $C.DriverVersion
Collate = $C.Collate
Color = $C.Color
Copies = $C.Copies
Duplex = $C.Duplex
PaperSize = $C.PaperSize
Orientation = $C.Orientation
PrintQuality = $C.PrintQuality
MediaType = $C.MediaType
DitherType = $C.DitherType
}
Break
}
}
}
#endregion
}
Catch {
Foreach ($P in $Using:Printers) {
@{
PrinterName = $P.Name
CimStatus = 'No admin permissions'
}
}
}
}
Foreach -parallel ($P in $Printers) {
$PrinterConfig = InlineScript {
$P = $Using:P
$Port = $Using:Ports | Where {$_.Name -eq $P.PortName}
$Driver = $Using:Drivers | Where {$_.Name -eq $P.DriverName}
Write-Verbose "$Using:S Printer '$($P.Name)'"
$DriverManufacturer = if ($Driver.Manufacturer) {$Driver.Manufacturer} else {
if ($Driver.Name -like '*Microsoft*') {'Microsoft'}
}
$DriverVersion = if ($Driver.DriverVersion -eq '0') {$null} else {
$Driver.DriverVersion
}
@{
Online_Hostname = if ($P.Name) {Test-Connection $P.Name -Quiet -EA Ignore} else {$null}
Online_PortHostAddress = if ($Port.PrinterHostAddress) {Test-Connection $Port.PrinterHostAddress -Quiet -EA Ignore} else {$null}
PortHostAddress = if ($Port.PrinterHostAddress) {$Port.PrinterHostAddress} else {$null}
PortDescription = if ($Port.Description) {$Port.Description} else {$null}
DriverType = $Driver.PrinterEnvironment -join ','
DriverManufacturer = ($DriverManufacturer | Select -Unique) -join ','
DriverVersion = ($DriverVersion | Select -Unique) -join ','
}
}
$Cim = $CimConfig | Where-Object -FilterScript {$P.Name -eq $_.PrinterName}
$P | Add-Member -NotePropertyMembers ($PrinterConfig + $Cim) -TypeName NoteProperty
}
InlineScript {
$Computer = $Using:Computer
$Computer.Printers = $Using:Printers
$Computer.ComputerStatus = 'Ok'
$Computer
}
}
else {
Write-Verbose "$S No printers found"
}
}
Catch {
InlineScript {
$Computer = $Using:Computer
if (Test-Connection $Using:S -Count 2 -Quiet) {
$Computer.ComputerStatus = $Using:_.Message
}
else {
$Computer.ComputerStatus = 'Offline'
}
$Computer
}
}
}
}