PowerBGInfo.psm1
function Get-ComputerBios { <# .SYNOPSIS Retrieves BIOS information from a remote or local computer. .DESCRIPTION This function retrieves BIOS information from a specified computer using CIM/WMI. .PARAMETER ComputerName Specifies the name of the computer to retrieve BIOS information from. Defaults to the local computer. .PARAMETER Protocol Specifies the protocol to use for communication. Valid values are 'Default', 'Dcom', or 'Wsman'. Default is 'Default'. .PARAMETER All Switch parameter to retrieve all available BIOS properties. .EXAMPLE Get-ComputerBios -ComputerName "RemoteComputer" -Protocol Wsman Retrieves BIOS information from a remote computer using the Wsman protocol. .EXAMPLE Get-ComputerBios -All Retrieves all available BIOS information from the local computer. #> [CmdletBinding()] param( [string] $ComputerName = $Env:COMPUTERNAME, [ValidateSet('Default', 'Dcom', 'Wsman')][string] $Protocol = 'Default', [switch] $All ) [string] $Class = 'win32_bios' if ($All) { [string] $Properties = '*' } else { [string[]] $Properties = 'PSComputerName', 'Status', 'Version', 'PrimaryBIOS', 'Manufacturer', 'ReleaseDate', 'SerialNumber', 'SMBIOSBIOSVersion', 'SMBIOSMajorVersion', 'SMBIOSMinorVersion', 'SystemBiosMajorVersion', 'SystemBiosMinorVersion' } $Information = Get-CimData -ComputerName $ComputerName -Protocol $Protocol -Class $Class -Properties $Properties if ($All) { $Information } else { foreach ($Info in $Information) { foreach ($Data in $Info) { [PSCustomObject] @{ ComputerName = if ($Data.PSComputerName) { $Data.PSComputerName } else { $Env:COMPUTERNAME } Status = $Data.Status Version = $Data.Version VersionBIOS = -join ($Data.SMBIOSMajorVersion, ".", $Data.SMBIOSMinorVersion, ".", $Data.SystemBiosMajorVersion, ".", $Data.SystemBiosMinorVersion) PrimaryBIOS = $Data.PrimaryBIOS Manufacturer = $Data.Manufacturer ReleaseDate = $Data.ReleaseDate } } } } } function Get-ComputerCPU { <# .SYNOPSIS Retrieves CPU information from specified computers. .DESCRIPTION This function retrieves CPU information from the specified computers. It provides details such as Name, DeviceID, Caption, SystemName, CurrentClockSpeed, MaxClockSpeed, ProcessorID, ThreadCount, Architecture, Status, LoadPercentage, L3CacheSize, Manufacturer, NumberOfCores, NumberOfEnabledCore, and NumberOfLogicalProcessors. .PARAMETER ComputerName Specifies the names of the computers for which to retrieve CPU information. .PARAMETER Protocol Specifies the protocol to use for retrieving CPU information. Valid values are 'Default', 'Dcom', and 'Wsman'. .PARAMETER All Indicates whether to retrieve all available CPU information. .EXAMPLE Get-ComputerCPU -ComputerName Server01, Server02 -Protocol Wsman -All Retrieves all available CPU information from remote computers Server01 and Server02 using Wsman protocol. .EXAMPLE Get-ComputerCPU -ComputerName "Workstation01" -Protocol Default Retrieves CPU information from a single remote computer named Workstation01 using the default protocol. #> [CmdletBinding()] param( [string[]] $ComputerName = $Env:COMPUTERNAME, [ValidateSet('Default', 'Dcom', 'Wsman')][string] $Protocol = 'Default', [switch] $All ) [string] $Class = 'win32_processor' if ($All) { [string] $Properties = '*' } else { [string[]] $Properties = 'PSComputerName', 'Name', 'DeviceID', 'Caption', 'SystemName', 'CurrentClockSpeed', 'MaxClockSpeed', 'ProcessorID', 'ThreadCount', 'Architecture', 'Status', 'LoadPercentage', 'L3CacheSize', 'Manufacturer', 'VirtualizationFirmwareEnabled', 'NumberOfCores', 'NumberOfEnabledCore', 'NumberOfLogicalProcessors' } $Information = Get-CimData -ComputerName $ComputerName -Protocol $Protocol -Class $Class -Properties $Properties if ($All) { $Information } else { foreach ($Info in $Information) { foreach ($Data in $Info) { [PSCustomObject] @{ ComputerName = if ($Data.PSComputerName) { $Data.PSComputerName } else { $Env:COMPUTERNAME } Name = $Data.Name DeviceID = $Data.DeviceID Caption = $Data.Caption CurrentClockSpeed = $Data.CurrentClockSpeed MaxClockSpeed = $Data.MaxClockSpeed ProcessorID = $Data.ProcessorID ThreadCount = $Data.ThreadCount Architecture = $Data.Architecture Status = $Data.Status LoadPercentage = $Data.LoadPercentage Manufacturer = $Data.Manufacturer NumberOfCores = $Data.NumberOfCores NumberOfEnabledCore = $Data.NumberOfEnabledCore NumberOfLogicalProcessors = $Data.NumberOfLogicalProcessors } } } } } function Get-ComputerOperatingSystem { <# .SYNOPSIS Retrieves operating system information from remote computers. .DESCRIPTION This function retrieves operating system information from remote computers using CIM/WMI queries. It provides details such as the operating system name, version, manufacturer, architecture, language, product suite, installation date, last boot-up time, and more. .PARAMETER ComputerName Specifies the name of the remote computer(s) to retrieve the operating system information from. Defaults to the local computer. .PARAMETER Protocol Specifies the protocol to use for the connection (Default, Dcom, or Wsman). Default is 'Default'. .PARAMETER All Switch parameter to retrieve all available properties of the operating system. .EXAMPLE Get-ComputerOperatingSystem -ComputerName "Server01" -Protocol Wsman Retrieves operating system information from a single remote computer named "Server01" using the Wsman protocol. .EXAMPLE Get-ComputerOperatingSystem -ComputerName "Server01", "Server02" -All Retrieves all available operating system properties from multiple remote computers named "Server01" and "Server02". #> [CmdletBinding()] param( [string[]] $ComputerName = $Env:COMPUTERNAME, [ValidateSet('Default', 'Dcom', 'Wsman')][string] $Protocol = 'Default', [switch] $All ) [string] $Class = 'win32_operatingsystem' if ($All) { [string] $Properties = '*' } else { [string[]] $Properties = 'Caption', 'Manufacturer', 'InstallDate', 'OSArchitecture', 'Version', 'SerialNumber', 'BootDevice', 'WindowsDirectory', 'CountryCode', 'OSLanguage', 'OSProductSuite', 'PSComputerName', 'LastBootUpTime', 'LocalDateTime' } $Information = Get-CimData -ComputerName $ComputerName -Protocol $Protocol -Class $Class -Properties $Properties if ($All) { $Information } else { foreach ($Data in $Information) { [PSCustomObject] @{ ComputerName = if ($Data.PSComputerName) { $Data.PSComputerName } else { $Env:COMPUTERNAME } OperatingSystem = $Data.Caption OperatingSystemVersion = ConvertTo-OperatingSystem -OperatingSystem $Data.Caption -OperatingSystemVersion $Data.Version OperatingSystemBuild = $Data.Version Manufacturer = $Data.Manufacturer OSArchitecture = $Data.OSArchitecture OSLanguage = ConvertFrom-LanguageCode -LanguageCode $Data.OSLanguage OSProductSuite = [Microsoft.PowerShell.Commands.OSProductSuite] $($Data.OSProductSuite) InstallDate = $Data.InstallDate LastBootUpTime = $Data.LastBootUpTime LocalDateTime = $Data.LocalDateTime SerialNumber = $Data.SerialNumber BootDevice = $Data.BootDevice WindowsDirectory = $Data.WindowsDirectory CountryCode = $Data.CountryCode } } } } function Get-ComputerRAM { <# .SYNOPSIS Retrieves information about the RAM of a specified computer. .DESCRIPTION This function retrieves detailed information about the RAM of a specified computer. It provides various properties such as Manufacturer, Model, Capacity, Speed, and more. .PARAMETER ComputerName Specifies the name of the computer to retrieve RAM information from. Defaults to the local computer. .PARAMETER Protocol Specifies the protocol to use for retrieving RAM information. Valid values are 'Default', 'Dcom', and 'Wsman'. Defaults to 'Default'. .PARAMETER All Indicates whether to retrieve all available properties of the RAM. If specified, all properties will be retrieved. .PARAMETER Extended Indicates whether to retrieve extended properties of the RAM. If specified, additional properties will be retrieved. .EXAMPLE Get-ComputerRAM -ComputerName "Server01" -Protocol Wsman Retrieves RAM information from a remote computer named Server01 using the Wsman protocol. .EXAMPLE Get-ComputerRAM -ComputerName "WorkstationA" -All Retrieves all available RAM properties from a computer named WorkstationA. #> [CmdletBinding()] param( [string] $ComputerName = $Env:COMPUTERNAME, [ValidateSet('Default', 'Dcom', 'Wsman')][string] $Protocol = 'Default', [switch] $All, [switch] $Extended ) [string] $Class = 'Win32_physicalmemory ' if ($All) { [string] $Properties = '*' } else { [string[]] $Properties = @( 'InstallDate' 'Manufacturer' 'Model' 'OtherIdentifyingInfo' 'PartNumber' 'PoweredOn' 'SerialNumber' 'SKU' 'Tag' 'Version' 'HotSwappable' 'Removable' 'Replaceable' 'FormFactor' 'BankLabel' 'Capacity' 'InterleavePosition' 'MemoryType' 'Speed' 'ConfiguredClockSpeed' 'ConfiguredVoltage' 'DeviceLocator' 'MaxVoltage' 'MinVoltage' 'SMBIOSMemoryType' 'TypeDetail' 'PSComputerName' ) } $FormFactor = @{ '0' = 'Unknown' '1' = 'Other' '2' = 'SIP' '3' = 'DIP' '4' = 'ZIP' '5' = 'SOJ' '6' = 'Proprietary' '7' = 'SIMM' '8' = 'DIMM' '9' = 'TSOP' '10' = 'PGA' '11' = 'RIMM' '12' = 'SODIMM' '13' = 'SRIMM' '14' = 'SMD' '15' = 'SSMP' '16' = 'QFP' '17' = 'TQFP' '18' = 'SOIC' '19' = 'LCC' '20' = 'PLCC' '21' = 'BGA' '22' = 'FPBGA' '23' = 'LGA' } $TypeDetails = @{ '1' = 'Reserved' '2' = 'Other' '4' = 'Unknown' '8' = 'Fast-paged' '16' = 'Static column' '32' = 'Pseudo-static' '64' = 'RAMBUS' '128' = 'Synchronous' '256' = 'CMOS' '512' = 'EDO' '1024' = 'Window DRAM' '2048' = 'Cache DRAM' '4096' = 'Non-volatile' } $InterleavePosition = @{ '0' = "Non-Interleaved" '1' = "First Position" '2' = "Second Position" } $MemoryType = @{ '0' = "Unknown" '1' = "Other" '2' = "DRAM" '3' = "Synchronous DRAM" '4' = "Cache DRAM" '5' = "EDO" '6' = "EDRAM" '7' = "VRAM" '8' = "SRAM" '9' = "ROM" '10' = "ROM" '11' = "FLASH" '12' = "EEPROM" '13' = "FEPROM" '14' = "EPROM" '15' = "CDRAM" '16' = "3DRAM" '17' = "SDRAM" '18' = "SGRAM" '19' = "RDRAM" '20' = "DDR" } $MemoryTypeSMBIOS = @{ '0' = 'Unknown' '1' = 'Other' '2' = 'DRAM' '3' = 'Synchronous DRAM' '4' = 'Cache DRAM' '5' = 'EDO' '6' = 'EDRAM' '7' = 'VRAM' '8' = 'SRAM' '9' = 'RAM' '10' = 'ROM' '11' = 'Flash' '12' = 'EEPROM' '13' = 'FEPROM' '14' = 'EPROM' '15' = 'CDRAM' '16' = '3DRAM' '17' = 'SDRAM' '18' = 'SGRAM' '19' = 'RDRAM' '20' = 'DDR' '21' = 'DDR2' '22' = 'DDR2 FB-DIMM' '24' = 'DDR3' '25' = 'FBD2' '26' = 'DDR4' } $Information = Get-CimData -ComputerName $ComputerName -Protocol $Protocol -Class $Class -Properties $Properties if ($All) { $Information } else { foreach ($Info in $Information) { foreach ($Data in $Info) { $Ram = [ordered] @{ ComputerName = if ($Data.PSComputerName) { $Data.PSComputerName } else { $Env:COMPUTERNAME } Manufacturer = $Data.Manufacturer FormFactor = $FormFactor["$($Data.FormFactor)"] SMBIOSMemoryType = $MemoryTypeSMBIOS["$($Data.SMBIOSMemoryType)"] Size = [math]::round($Data.Capacity / 1GB, 2) Speed = $Data.Speed InterleavePosition = $InterleavePosition["$($Data.InterleavePosition)"] MemoryType = $MemoryType["$($Data.MemoryType)"] TypeDetail = $TypeDetails["$($Data.TypeDetail)"] PartNumber = $Data.PartNumber DeviceLocator = $Data.DeviceLocator } if ($Extended) { $RamExtended = [ordered] @{ InstallDate = $Data.InstallDate Model = $Data.Model OtherIdentifyingInfo = $Data.OtherIdentifyingInfo PoweredOn = $Data.PoweredOn SerialNumber = $Data.SerialNumber SKU = $Data.SKU Tag = $Data.Tag Version = $Data.Version HotSwappable = $Data.HotSwappable Removable = $Data.Removable Replaceable = $Data.Replaceable BankLabel = $Data.BankLabel ConfiguredClockSpeed = $Data.ConfiguredClockSpeed ConfiguredVoltage = $Data.ConfiguredVoltage MaxVoltage = $Data.MaxVoltage MinVoltage = $Data.MinVoltage } [PSCustomObject] ($Ram + $RamExtended) } else { [PSCustomObject] $Ram } } } } } function ConvertFrom-LanguageCode { <# .SYNOPSIS Converts a language code to its corresponding language name. .DESCRIPTION This function takes a language code as input and returns the corresponding language name. .PARAMETER LanguageCode The language code to convert to a language name. .EXAMPLE ConvertFrom-LanguageCode -LanguageCode 1033 Returns: "English (United States)" .EXAMPLE ConvertFrom-LanguageCode -LanguageCode 1041 Returns: "Japanese" #> [cmdletBinding()] param( [string] $LanguageCode ) $LanguageCodeDictionary = @{ '1' = "Arabic" '4' = "Chinese (Simplified)?? China" '9' = "English" '1025' = "Arabic (Saudi Arabia)" '1026' = "Bulgarian" '1027' = "Catalan" '1028' = "Chinese (Traditional) Taiwan" '1029' = "Czech" '1030' = "Danish" '1031' = "German (Germany)" '1032' = "Greek" '1033' = "English (United States)" '1034' = "Spanish (Traditional Sort)" '1035' = "Finnish" '1036' = "French (France)" '1037' = "Hebrew" '1038' = "Hungarian" '1039' = "Icelandic" '1040' = "Italian (Italy)" '1041' = "Japanese" '1042' = "Korean" '1043' = "Dutch (Netherlands)" '1044' = "Norwegian (Bokmal)" '1045' = "Polish" '1046' = "Portuguese (Brazil)" '1047' = "Rhaeto-Romanic" '1048' = "Romanian" '1049' = "Russian" '1050' = "Croatian" '1051' = "Slovak" '1052' = "Albanian" '1053' = "Swedish" '1054' = "Thai" '1055' = "Turkish" '1056' = "Urdu" '1057' = "Indonesian" '1058' = "Ukrainian" '1059' = "Belarusian" '1060' = "Slovenian" '1061' = "Estonian" '1062' = "Latvian" '1063' = "Lithuanian" '1065' = "Persian" '1066' = "Vietnamese" '1069' = "Basque (Basque)" '1070' = "Serbian" '1071' = "Macedonian (FYROM)" '1072' = "Sutu" '1073' = "Tsonga" '1074' = "Tswana" '1076' = "Xhosa" '1077' = "Zulu" '1078' = "Afrikaans" '1080' = "Faeroese" '1081' = "Hindi" '1082' = "Maltese" '1084' = "Scottish Gaelic (United Kingdom)" '1085' = "Yiddish" '1086' = "Malay (Malaysia)" '2049' = "Arabic (Iraq)" '2052' = "Chinese (Simplified) PRC" '2055' = "German (Switzerland)" '2057' = "English (United Kingdom)" '2058' = "Spanish (Mexico)" '2060' = "French (Belgium)" '2064' = "Italian (Switzerland)" '2067' = "Dutch (Belgium)" '2068' = "Norwegian (Nynorsk)" '2070' = "Portuguese (Portugal)" '2072' = "Romanian (Moldova)" '2073' = "Russian (Moldova)" '2074' = "Serbian (Latin)" '2077' = "Swedish (Finland)" '3073' = "Arabic (Egypt)" '3076' = "Chinese Traditional (Hong Kong SAR)" '3079' = "German (Austria)" '3081' = "English (Australia)" '3082' = "Spanish (International Sort)" '3084' = "French (Canada)" '3098' = "Serbian (Cyrillic)" '4097' = "Arabic (Libya)" '4100' = "Chinese Simplified (Singapore)" '4103' = "German (Luxembourg)" '4105' = "English (Canada)" '4106' = "Spanish (Guatemala)" '4108' = "French (Switzerland)" '5121' = "Arabic (Algeria)" '5127' = "German (Liechtenstein)" '5129' = "English (New Zealand)" '5130' = "Spanish (Costa Rica)" '5132' = "French (Luxembourg)" '6145' = "Arabic (Morocco)" '6153' = "English (Ireland)" '6154' = "Spanish (Panama)" '7169' = "Arabic (Tunisia)" '7177' = "English (South Africa)" '7178' = "Spanish (Dominican Republic)" '8193' = "Arabic (Oman)" '8201' = "English (Jamaica)" '8202' = "Spanish (Venezuela)" '9217' = "Arabic (Yemen)" '9226' = "Spanish (Colombia)" '10241' = "Arabic (Syria)" '10249' = "English (Belize)" '10250' = "Spanish (Peru)" '11265' = "Arabic (Jordan)" '11273' = "English (Trinidad)" '11274' = "Spanish (Argentina)" '12289' = "Arabic (Lebanon)" '12298' = "Spanish (Ecuador)" '13313' = "Arabic (Kuwait)" '13322' = "Spanish (Chile)" '14337' = "Arabic (U.A.E.)" '14346' = "Spanish (Uruguay)" '15361' = "Arabic (Bahrain)" '15370' = "Spanish (Paraguay)" '16385' = "Arabic (Qatar)" '16394' = "Spanish (Bolivia)" '17418' = "Spanish (El Salvador)" '18442' = "Spanish (Honduras)" '19466' = "Spanish (Nicaragua)" '20490' = "Spanish (Puerto Rico)" } $Output = $LanguageCodeDictionary[$LanguageCode] if ($Output) { $Output } else { "Unknown (Undocumented)" } } function ConvertTo-OperatingSystem { <# .SYNOPSIS Allows easy conversion of OperatingSystem, Operating System Version to proper Windows 10 naming based on WMI or AD .DESCRIPTION Allows easy conversion of OperatingSystem, Operating System Version to proper Windows 10 naming based on WMI or AD .PARAMETER OperatingSystem Operating System as returned by Active Directory .PARAMETER OperatingSystemVersion Operating System Version as returned by Active Directory .EXAMPLE $Computers = Get-ADComputer -Filter * -Properties OperatingSystem, OperatingSystemVersion | ForEach-Object { $OPS = ConvertTo-OperatingSystem -OperatingSystem $_.OperatingSystem -OperatingSystemVersion $_.OperatingSystemVersion Add-Member -MemberType NoteProperty -Name 'OperatingSystemTranslated' -Value $OPS -InputObject $_ -Force $_ } $Computers | Select-Object DNS*, Name, SamAccountName, Enabled, OperatingSystem*, DistinguishedName | Format-Table .EXAMPLE $Registry = Get-PSRegistry -ComputerName 'AD1' -RegistryPath 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion' ConvertTo-OperatingSystem -OperatingSystem $Registry.ProductName -OperatingSystemVersion $Registry.CurrentBuildNumber .NOTES General notes #> [CmdletBinding()] param( [string] $OperatingSystem, [string] $OperatingSystemVersion ) if ($OperatingSystem -like 'Windows 10*' -or $OperatingSystem -like 'Windows 11*') { $Systems = @{ '10.0 (22621)' = 'Windows 11 22H2' '10.0 (22000)' = 'Windows 11 21H2' '10.0 (19045)' = 'Windows 10 22H2' '10.0 (19044)' = 'Windows 10 21H2' '10.0 (19043)' = 'Windows 10 21H1' '10.0 (19042)' = 'Windows 10 20H2' '10.0 (19041)' = 'Windows 10 2004' '10.0 (18898)' = 'Windows 10 Insider Preview' '10.0 (18363)' = "Windows 10 1909" '10.0 (18362)' = "Windows 10 1903" '10.0 (17763)' = "Windows 10 1809" '10.0 (17134)' = "Windows 10 1803" '10.0 (16299)' = "Windows 10 1709" '10.0 (15063)' = "Windows 10 1703" '10.0 (14393)' = "Windows 10 1607" '10.0 (10586)' = "Windows 10 1511" '10.0 (10240)' = "Windows 10 1507" '10.0.22621' = 'Windows 11 22H2' '10.0.22000' = 'Windows 11 21H2' '10.0.19045' = 'Windows 10 22H2' '10.0.19044' = 'Windows 10 21H2' '10.0.19043' = 'Windows 10 21H1' '10.0.19042' = 'Windows 10 20H2' '10.0.19041' = 'Windows 10 2004' '10.0.18898' = 'Windows 10 Insider Preview' '10.0.18363' = "Windows 10 1909" '10.0.18362' = "Windows 10 1903" '10.0.17763' = "Windows 10 1809" '10.0.17134' = "Windows 10 1803" '10.0.16299' = "Windows 10 1709" '10.0.15063' = "Windows 10 1703" '10.0.14393' = "Windows 10 1607" '10.0.10586' = "Windows 10 1511" '10.0.10240' = "Windows 10 1507" '22621' = 'Windows 11 22H2' '22000' = 'Windows 11 21H2' '19045' = 'Windows 10 22H2' '19044' = 'Windows 10 21H2' '19043' = 'Windows 10 21H1' '19042' = 'Windows 10 20H2' '19041' = 'Windows 10 2004' '18898' = 'Windows 10 Insider Preview' '18363' = "Windows 10 1909" '18362' = "Windows 10 1903" '17763' = "Windows 10 1809" '17134' = "Windows 10 1803" '16299' = "Windows 10 1709" '15063' = "Windows 10 1703" '14393' = "Windows 10 1607" '10586' = "Windows 10 1511" '10240' = "Windows 10 1507" } $System = $Systems[$OperatingSystemVersion] if (-not $System) { $System = $OperatingSystemVersion } } elseif ($OperatingSystem -like 'Windows Server*') { $Systems = @{ '10.0 (20348)' = 'Windows Server 2022' '10.0 (19042)' = 'Windows Server 2019 20H2' '10.0 (19041)' = 'Windows Server 2019 2004' '10.0 (18363)' = 'Windows Server 2019 1909' '10.0 (18362)' = "Windows Server 2019 1903" '10.0 (17763)' = "Windows Server 2019 1809" '10.0 (17134)' = "Windows Server 2016 1803" '10.0 (14393)' = "Windows Server 2016 1607" '6.3 (9600)' = 'Windows Server 2012 R2' '6.1 (7601)' = 'Windows Server 2008 R2' '5.2 (3790)' = 'Windows Server 2003' '10.0.20348' = 'Windows Server 2022' '10.0.19042' = 'Windows Server 2019 20H2' '10.0.19041' = 'Windows Server 2019 2004' '10.0.18363' = 'Windows Server 2019 1909' '10.0.18362' = "Windows Server 2019 1903" '10.0.17763' = "Windows Server 2019 1809" '10.0.17134' = "Windows Server 2016 1803" '10.0.14393' = "Windows Server 2016 1607" '6.3.9600' = 'Windows Server 2012 R2' '6.1.7601' = 'Windows Server 2008 R2' '5.2.3790' = 'Windows Server 2003' '20348' = 'Windows Server 2022' '19042' = 'Windows Server 2019 20H2' '19041' = 'Windows Server 2019 2004' '18363' = 'Windows Server 2019 1909' '18362' = "Windows Server 2019 1903" '17763' = "Windows Server 2019 1809" '17134' = "Windows Server 2016 1803" '14393' = "Windows Server 2016 1607" '9600' = 'Windows Server 2012 R2' '7601' = 'Windows Server 2008 R2' '3790' = 'Windows Server 2003' } $System = $Systems[$OperatingSystemVersion] if (-not $System) { $System = $OperatingSystemVersion } } else { $System = $OperatingSystem } if ($System) { $System } else { 'Unknown' } } function Get-CimData { <# .SYNOPSIS Helper function for retreiving CIM data from local and remote computers .DESCRIPTION Helper function for retreiving CIM data from local and remote computers .PARAMETER ComputerName Specifies computer on which you want to run the CIM operation. You can specify a fully qualified domain name (FQDN), a NetBIOS name, or an IP address. If you do not specify this parameter, the cmdlet performs the operation on the local computer using Component Object Model (COM). .PARAMETER Protocol Specifies the protocol to use. The acceptable values for this parametDer are: DCOM, Default, or Wsman. .PARAMETER Class Specifies the name of the CIM class for which to retrieve the CIM instances. You can use tab completion to browse the list of classes, because PowerShell gets a list of classes from the local WMI server to provide a list of class names. .PARAMETER Properties Specifies a set of instance properties to retrieve. Use this parameter when you need to reduce the size of the object returned, either in memory or over the network. The object returned also contains the key properties even if you have not listed them using the Property parameter. Other properties of the class are present but they are not populated. .PARAMETER NameSpace Specifies the namespace for the CIM operation. The default namespace is root\cimv2. You can use tab completion to browse the list of namespaces, because PowerShell gets a list of namespaces from the local WMI server to provide a list of namespaces. .PARAMETER Credential Specifies a user account that has permission to perform this action. The default is the current user. .EXAMPLE Get-CimData -Class 'win32_bios' -ComputerName AD1,EVOWIN .EXAMPLE Get-CimData -Class 'win32_bios' .EXAMPLE Get-CimClass to get all classes .NOTES General notes #> [CmdletBinding()] param( [parameter(Mandatory)][string] $Class, [string] $NameSpace = 'root\cimv2', [string[]] $ComputerName = $Env:COMPUTERNAME, [ValidateSet('Default', 'Dcom', 'Wsman')][string] $Protocol = 'Default', [pscredential] $Credential, [string[]] $Properties = '*' ) $ExcludeProperties = 'CimClass', 'CimInstanceProperties', 'CimSystemProperties', 'SystemCreationClassName', 'CreationClassName' [Array] $ComputersSplit = Get-ComputerSplit -ComputerName $ComputerName $CimObject = @( [string[]] $PropertiesOnly = $Properties | Where-Object { $_ -ne 'PSComputerName' } $Computers = $ComputersSplit[1] if ($Computers.Count -gt 0) { if ($Protocol -eq 'Default' -and $null -eq $Credential) { Get-CimInstance -ClassName $Class -ComputerName $Computers -ErrorAction SilentlyContinue -Property $PropertiesOnly -Namespace $NameSpace -Verbose:$false -ErrorVariable ErrorsToProcess | Select-Object -Property $Properties -ExcludeProperty $ExcludeProperties } else { $Option = New-CimSessionOption -Protocol $Protocol $newCimSessionSplat = @{ ComputerName = $Computers SessionOption = $Option ErrorAction = 'SilentlyContinue' } if ($Credential) { $newCimSessionSplat['Credential'] = $Credential } $Session = New-CimSession @newCimSessionSplat -Verbose:$false if ($Session) { Try { $Info = Get-CimInstance -ClassName $Class -CimSession $Session -ErrorAction Stop -Property $PropertiesOnly -Namespace $NameSpace -Verbose:$false -ErrorVariable ErrorsToProcess | Select-Object -Property $Properties -ExcludeProperty $ExcludeProperties } catch { Write-Warning -Message "Get-CimData - No data for computer $($E.OriginInfo.PSComputerName). Failed with errror: $($E.Exception.Message)" } try { $null = Remove-CimSession -CimSession $Session -ErrorAction SilentlyContinue } catch { Write-Warning -Message "Get-CimData - Failed to remove CimSession $($Session). Failed with errror: $($E.Exception.Message)" } $Info } else { Write-Warning -Message "Get-CimData - Failed to create CimSession for $($Computers). Problem with credentials?" } } foreach ($E in $ErrorsToProcess) { Write-Warning -Message "Get-CimData - No data for computer $($E.OriginInfo.PSComputerName). Failed with errror: $($E.Exception.Message)" } } else { $Computers = $ComputersSplit[0] if ($Computers.Count -gt 0) { $Info = Get-CimInstance -ClassName $Class -ErrorAction SilentlyContinue -Property $PropertiesOnly -Namespace $NameSpace -Verbose:$false -ErrorVariable ErrorsLocal | Select-Object -Property $Properties -ExcludeProperty $ExcludeProperties $Info | Add-Member -Name 'PSComputerName' -Value $Computers -MemberType NoteProperty -Force $Info } foreach ($E in $ErrorsLocal) { Write-Warning -Message "Get-CimData - No data for computer $($Env:COMPUTERNAME). Failed with errror: $($E.Exception.Message)" } } ) $CimObject } function Get-ComputerSplit { <# .SYNOPSIS This function splits the list of computer names provided into two arrays: one containing remote computers and another containing the local computer. .DESCRIPTION The Get-ComputerSplit function takes an array of computer names as input and splits them into two arrays based on whether they are remote computers or the local computer. It determines the local computer by comparing the provided computer names with the local computer name and DNS name. .PARAMETER ComputerName Specifies an array of computer names to split into remote and local computers. .EXAMPLE Get-ComputerSplit -ComputerName "Computer1", "Computer2", $Env:COMPUTERNAME This example splits the computer names "Computer1" and "Computer2" into the remote computers array and the local computer array based on the local computer's name. #> [CmdletBinding()] param( [string[]] $ComputerName ) if ($null -eq $ComputerName) { $ComputerName = $Env:COMPUTERNAME } try { $LocalComputerDNSName = [System.Net.Dns]::GetHostByName($Env:COMPUTERNAME).HostName } catch { $LocalComputerDNSName = $Env:COMPUTERNAME } $ComputersLocal = $null [Array] $Computers = foreach ($Computer in $ComputerName) { if ($Computer -eq '' -or $null -eq $Computer) { $Computer = $Env:COMPUTERNAME } if ($Computer -ne $Env:COMPUTERNAME -and $Computer -ne $LocalComputerDNSName) { $Computer } else { $ComputersLocal = $Computer } } , @($ComputersLocal, $Computers) } function New-BGInfo { <# .SYNOPSIS Provides a simple way to create PowerBGInfo configuration. .DESCRIPTION Provides a simple way to create PowerBGInfo configuration. It allows writting useful information on your desktop background. Every time the script is run, it will update existing image with new information. .PARAMETER BGInfoContent Special parameter that works as a scriptblock. It takes input and converts it into configuration. By using New-BGInfoLabel and New-BGInfoValue along with other supported PowerShell commands you can create your own configuration. .PARAMETER FilePath Path to the image that will be used as a background. If not provided current Desktop Background will be used. .PARAMETER ConfigurationDirectory Path to the directory where configuration will be stored, and where image for desktop background will be placed. If not provided, it will be stored in C:\TEMP .PARAMETER FontFamilyName Font family name that will be used to display information for Label. It's only used if New-BGInfoLabel or New-BGIInfoValue doesn't provide it's own value. If ValueFontFamilyName is not provided it will be used as a default value for that property as well .PARAMETER Color Color that will be used to display information for Label. It's only used if New-BGInfoLabel or New-BGIInfoValue doesn't provide it's own value. If ValueColor is not provided it will be used as a default value for that property as well .PARAMETER FontSize Font size that will be used to display information for Label. It's only used if New-BGInfoLabel or New-BGIInfoValue doesn't provide it's own value. If ValueFontSize is not provided it will be used as a default value for that property as well .PARAMETER ValueColor Color that will be used to display information for Value. It's only used if New-BGInfoLabel or New-BGIInfoValue doesn't provide it's own value. If not provided it will be taken from Color property. .PARAMETER ValueFontSize Font size that will be used to display information for Value. It's only used if New-BGInfoLabel or New-BGIInfoValue doesn't provide it's own value. If not provided it will be taken from FontSize property. .PARAMETER ValueFontFamilyName Font family name that will be used to display information for Value. It's only used if New-BGInfoLabel or New-BGIInfoValue doesn't provide it's own value. If not provided it will be taken from FontFamilyName property. .PARAMETER SpaceBetweenLines Length of the space between lines .PARAMETER SpaceBetweenColumns Length of the space between columns (Label and Value) .PARAMETER PositionX Position of the first column on the X axis. .PARAMETER PositionY Position of the first column on the Y axis. .PARAMETER MonitorIndex Index of the monitor that will be used to display the background image. By default it will be 0 (first monitor) .PARAMETER WallpaperFit WHat to do with the image if it is not the same size as the monitor resolution. It can be one of the following: 'Center', 'Fit', 'Stretch', 'Tile', 'Span', 'Fill' .EXAMPLE New-BGInfo -MonitorIndex 0 { # Lets add computer name, but lets use builtin values for that New-BGInfoValue -BuiltinValue HostName -Color Red -FontSize 20 -FontFamilyName 'Calibri' New-BGInfoValue -BuiltinValue FullUserName New-BGInfoValue -BuiltinValue CpuName New-BGInfoValue -BuiltinValue CpuLogicalCores New-BGInfoValue -BuiltinValue RAMSize New-BGInfoValue -BuiltinValue RAMSpeed # Lets add Label, but without any values, kinf of like section starting New-BGInfoLabel -Name "Drives" -Color LemonChiffon -FontSize 16 -FontFamilyName 'Calibri' # Lets get all drives and their labels foreach ($Disk in (Get-Disk)) { $Volumes = $Disk | Get-Partition | Get-Volume foreach ($V in $Volumes) { New-BGInfoValue -Name "Drive $($V.DriveLetter)" -Value $V.SizeRemaining } } } -FilePath $PSScriptRoot\Samples\PrzemyslawKlysAndKulkozaurr.jpg -ConfigurationDirectory $PSScriptRoot\Output -PositionX 100 -PositionY 100 -WallpaperFit Center .NOTES General notes #> [CmdletBinding()] param( [parameter(Mandatory)][scriptblock] $BGInfoContent, [string] $FilePath, [parameter(Mandatory)][string] $ConfigurationDirectory, [string] $FontFamilyName = 'Calibri', [SixLabors.ImageSharp.Color] $Color = [SixLabors.ImageSharp.Color]::Black, [int] $FontSize = 16, [SixLabors.ImageSharp.Color] $ValueColor = [SixLabors.ImageSharp.Color]::Black, [float] $ValueFontSize = 16, [string] $ValueFontFamilyName = 'Calibri', [int] $SpaceBetweenLines = 10, [int] $SpaceBetweenColumns = 30, [int] $PositionX = 10, [int] $PositionY = 10, [int] $MonitorIndex = 0, [ValidateSet('Center', 'Fit', 'Stretch', 'Tile', 'Span', 'Fill')][string] $WallpaperFit ) $ConfigurationPath = [io.path]::Combine($ConfigurationDirectory, "PowerBGInfoConfiguration.xml") if (Test-Path -LiteralPath $ConfigurationPath) { $Configuration = Import-Clixml -LiteralPath $ConfigurationPath } else { $Configuration = [ordered] @{ OriginalImage = '' } } if ($FilePath -eq "") { $WallpaperPath = Get-DesktopWallpaper -Index $MonitorIndex } else { $WallpaperPath = $FilePath } if ($WallpaperPath -eq "" -or (Test-Path -LiteralPath $WallpaperPath) -eq $false) { Write-Warning -Message "New-BGInfo - Wallpaper ($WallpaperPath) not found. Provide new wallpaper, or make sure one is already set." return } # if ($Configuration['OriginalImage'] -ne "") { # Write-Verbose -Message "New-BGInfo - Wallpaper ($WallpaperPath) already has BGInfo applied, reusing what is set." #} else { $Configuration['OriginalImage'] = $WallpaperPath #} # Copy wallpaper to use as a base $FileName = [io.path]::GetFileName($Configuration['OriginalImage']) $FileNameWithoutExtension = [io.path]::GetFileNameWithoutExtension(($Configuration['OriginalImage'])) $FileNameExtension = [io.path]::GetExtension($FileName) $NewFileName = "$($FileNameWithoutExtension)_PowerBgInfo" + $FileNameExtension $FilePathOutput = [io.path]::Combine($ConfigurationDirectory, $NewFileName) # Wallpaper and output are the same file, if so, we already applied BGInfo at least once if ($FilePathOutput -ne $Configuration['OriginalImage'] ) { Copy-Item -Path $Configuration['OriginalImage'] -Destination $FilePathOutput -Force } # We need to check if file exists, because Copy-Item may not do what it's supposed to do if ($FilePathOutput -eq "" -or (Test-Path -LiteralPath $FilePathOutput) -eq $false) { Write-Warning -Message "New-BGInfo - Wallpaper ($FilePathOutput) not found. Copying failed?" return } # Load the file $Image = Get-Image -FilePath $FilePathOutput $BGContent = & $BGInfoContent # Do assesment of the longest text so we can make sure columns are not overlapping $HighestWidth = 0 $HighestHeight = 0 foreach ($Info in $BGContent) { if ($Info.Color) { #$SetColor = $Info.Color } else { $Info.Color = $Color } if ($Info.FontSize) { #$SetFontSize = $Info.FontSize } else { $Info.FontSize = $FontSize } if ($Info.FontFamilyName) { #$SetFontFamilyName = $Info.FontFamilyName } else { $Info.FontFamilyName = $FontFamilyName } if ($Info.Type -ne 'Label') { if ($Info.ValueColor) { #$SetValueColor = $Info.ValueColor } else { if ($Info.Color) { $Info.ValueColor = $Info.Color } else { $Info.ValueColor = $ValueColor } } if ($Info.ValueFontSize) { #$SetValueFontSize = $Info.ValueFontSize } else { if ($Info.FontSize) { $Info.ValueFontSize = $Info.FontSize } else { $Info.ValueFontSize = $ValueFontSize } } if ($Info.ValueFontFamilyName) { # $SetValueFontFamilyName = $Info.ValueFontFamilyName } else { if ($Info.FontFamilyName) { $Info.ValueFontFamilyName = $Info.FontFamilyName } else { $Info.ValueFontFamilyName = $ValueFontFamilyName } } } $SizeOfText = $Image.GetTextSize($Info.Name, $Info.FontSize, $Info.FontFamilyName) if ($SizeOfText.Width -gt $HighestWidth) { $HighestWidth = $SizeOfText.Width } if ($SizeOfText.Height -gt $HighestHeight) { $HighestHeight = $SizeOfText.Height } } # Add text foreach ($Info in $BGContent) { if ($Info.Type -eq 'Label') { $Image.AddText($PositionX, $PositionY, $Info.Name, $Info.Color, $Info.FontSize, $Info.FontFamilyName) } else { $Image.AddText($PositionX, $PositionY, $Info.Name, $Info.Color, $Info.FontSize, $Info.FontFamilyName) $Image.AddText($PositionX + $HighestWidth + $SpaceBetweenColumns, $PositionY, $Info.Value, $Info.ValueColor, $Info.ValueFontSize, $Info.ValueFontFamilyName) } $PositionY += $HighestHeight + $SpaceBetweenLines } # lets now save image after modifications Save-Image -Image $Image -FilePath $FilePathOutput # finally lets set the image as wallpapeer if ($WallpaperFit) { Set-DesktopWallpaper -Index $MonitorIndex -FilePath $FilePathOutput -Position $WallpaperFit } else { Set-DesktopWallpaper -Index $MonitorIndex -FilePath $FilePathOutput } # lets export configuration, so we know what was done $Configuration | Export-Clixml -LiteralPath $ConfigurationPath -Force } function New-BGInfoLabel { <# .SYNOPSIS Provides ability to set label without value. It can be used to separate different sections of information. .DESCRIPTION Provides ability to set label without value. It can be used to separate different sections of information. .PARAMETER Name Name of the label/section .PARAMETER Color Color for the label. If not provided it will be taken from the parent New-BGInfo command. .PARAMETER FontSize Font size for the label. If not provided it will be taken from the parent New-BGInfo command. .PARAMETER FontFamilyName Font family name for the label. If not provided it will be taken from the parent New-BGInfo command. .EXAMPLE # Lets add Label, but without any values, kinf of like section starting New-BGInfoLabel -Name "Drives" -Color LemonChiffon -FontSize 16 -FontFamilyName 'Calibri' .NOTES General notes #> [CmdletBinding()] param( [string] $Name, [SixLabors.ImageSharp.Color] $Color, [float] $FontSize, [string] $FontFamilyName ) [PSCustomObject] @{ Type = 'Label' Name = $Name Color = $Color FontSize = $FontSize FontFamilyName = $FontFamilyName } } function New-BGInfoValue { <# .SYNOPSIS Special function that provides a way to create a value that will be displayed on the background image. .DESCRIPTION Special function that provides a way to create a value that will be displayed on the background image. It allows using builtin values, or custom values depending on user needs. .PARAMETER Name Label that will be used on the left side of the value. .PARAMETER Value Cystom Value that will be displayed on the right side of the label. .PARAMETER BuiltinValue Builtin value that will be displayed on the right side of the label. It can be one of the following: - UserName - Current user name - HostName - Current host name - FullUserName - Current user name with domain - CpuName - CPU name - CpuMaxClockSpeed - CPU max clock speed - CpuCores - CPU cores - CpuLogicalCores - CPU logical cores - RAMSize - RAM size - RAMSpeed - RAM speed - RAMPartNumber - RAM part number - BiosVersion - BIOS version - BiosManufacturer - BIOS manufacturer - BiosReleaseDate - BIOS release date - OSName - OS name - OSVersion - OS version - OSArchitecture - OS architecture - OSBuild - OS build - OSInstallDate - OS install date - OSLastBootUpTime - OS last boot up time - UserDNSDomain - User DNS domain - FQDN - Fully qualified domain name - IPv4Address - IPv4 address - IPv6Address - IPv6 address .PARAMETER Color Color for the label. If not provided it will be taken from the parent New-BGInfo command. .PARAMETER FontSize Font size for the label. If not provided it will be taken from the parent New-BGInfo command. .PARAMETER FontFamilyName Font family name for the label. If not provided it will be taken from the parent New-BGInfo command. .PARAMETER ValueColor Color for the value. If not provided it will be taken first from Color of the label and if that is not provided from the parent New-BGInfo command. .PARAMETER ValueFontSize Font size for the value. If not provided it will be taken first from FontSize of the label and if that is not provided from the parent New-BGInfo command. .PARAMETER ValueFontFamilyName Font family name for the value. If not provided it will be taken first from FontFamilyName of the label and if that is not provided from the parent New-BGInfo command. .EXAMPLE New-BGInfoValue -BuiltinValue HostName -Color Red -FontSize 20 -FontFamilyName 'Calibri' New-BGInfoValue -BuiltinValue FullUserName New-BGInfoValue -BuiltinValue CpuName .EXAMPLE # Lets get all drives and their labels foreach ($Disk in (Get-Disk)) { $Volumes = $Disk | Get-Partition | Get-Volume foreach ($V in $Volumes) { New-BGInfoValue -Name "Drive $($V.DriveLetter)" -Value $V.SizeRemaining } } .NOTES General notes #> [CmdletBinding(DefaultParameterSetName = 'Values')] param( [parameter(ParameterSetName = 'Builtin')] [parameter(ParameterSetName = 'Values', Mandatory)] [string] $Name, [parameter(ParameterSetName = 'Values', Mandatory)] [string] $Value, [parameter(ParameterSetName = 'Builtin', Mandatory)] [ValidateSet( 'UserName', 'HostName', 'FullUserName', 'CpuName', 'CpuMaxClockSpeed', 'CpuCores', 'CpuLogicalCores', 'RAMSize', 'RAMSpeed', 'RAMPartNumber', 'BiosVersion', 'BiosManufacturer', 'BiosReleaseDate', 'OSName', 'OSVersion', 'OSArchitecture', 'OSBuild', 'OSInstallDate', 'OSLastBootUpTime', 'UserDNSDomain', 'FQDN', 'IPv4Address', 'IPv6Address' )][string] $BuiltinValue, [parameter(ParameterSetName = 'Values')] [parameter(ParameterSetName = 'Builtin')] [SixLabors.ImageSharp.Color] $Color, [parameter(ParameterSetName = 'Values')] [parameter(ParameterSetName = 'Builtin')] [float] $FontSize, [parameter(ParameterSetName = 'Values')] [parameter(ParameterSetName = 'Builtin')] [string] $FontFamilyName, [parameter(ParameterSetName = 'Values')] [parameter(ParameterSetName = 'Builtin')] [SixLabors.ImageSharp.Color] $ValueColor, [parameter(ParameterSetName = 'Values')] [parameter(ParameterSetName = 'Builtin')] [float] $ValueFontSize, [parameter(ParameterSetName = 'Values')] [parameter(ParameterSetName = 'Builtin')] [string] $ValueFontFamilyName ) if ($BuiltinValue) { if ($BuiltinValue -in 'CPUName', 'CpuMaxClockSpeed', 'CpuCores', 'CpuLogicalCores') { $ComputerCPU = Get-ComputerCPU } elseif ($BuiltinValue -in 'RAMSize', 'RAMSpeed', 'RAMPartNumber') { $ComputerRAM = Get-ComputerRAM } elseif ($BuiltinValue -in 'BiosVersion', 'BiosManufacturer', 'BiosReleaseDate') { $ComputerBios = Get-ComputerBios } elseif ($BuiltinValue -in 'OSName', 'OSVersion', 'OSArchitecture', 'OSBuild', 'OSInstallDate', 'OSLastBootUpTime') { $ComputerOS = Get-ComputerOperatingSystem } if ($BuiltinValue -eq 'UserName') { $SetValue = $env:USERNAME } elseif ($BuiltinValue -eq 'HostName') { $SetValue = $env:COMPUTERNAME } elseif ($BuiltinValue -eq 'FullUserName') { $SetValue = $env:USERDOMAIN + '\' + $env:USERNAME } elseif ($BuiltinValue -eq 'CPUName') { $SetValue = $ComputerCPU.Name } elseif ($BuiltinValue -eq 'CpuMaxClockSpeed') { $SetValue = $ComputerCPU.MaxClockSpeed } elseif ($BuiltinValue -eq 'CpuCores') { $SetValue = $ComputerCPU.NumberOfEnabledCore } elseif ($BuiltinValue -eq 'CpuLogicalCores') { $SetValue = $ComputerCPU.NumberOfLogicalProcessors } elseif ($BuiltinValue -eq 'RAMSize') { $SetValue = ($ComputerRAM.Size | ForEach-Object { $_.ToString('N0') + 'GB' }) -join " / " } elseif ($BuiltinValue -eq 'RAMSpeed') { $SetValue = ($ComputerRAM.Speed | ForEach-Object { $_.ToString('N0') + 'MHz' }) -join " / " } elseif ($BuiltinValue -eq 'RAMPartNumber') { $SetValue = $ComputerRAM.PartNumber.Trim() -join ", " } elseif ($BuiltinValue -eq 'BiosVersion') { $SetValue = $ComputerBios.Version } elseif ($BuiltinValue -eq 'BiosManufacturer') { $SetValue = $ComputerBios.Manufacturer } elseif ($BuiltinValue -eq 'BiosReleaseDate') { $SetValue = $ComputerBios.ReleaseDate } elseif ($BuiltinValue -eq 'OSName') { $SetValue = $ComputerOS.OperatingSystem } elseif ($BuiltinValue -eq 'OSVersion') { $SetValue = $ComputerOS.OperatingSystemVersion } elseif ($BuiltinValue -eq 'OSArchitecture') { $SetValue = $ComputerOS.OSArchitecture } elseif ($BuiltinValue -eq 'OSBuild') { $SetValue = $ComputerOS.OperatingSystemBuild } elseif ($BuiltinValue -eq 'OSInstallDate') { $SetValue = $ComputerOS.InstallDate } elseif ($BuiltinValue -eq 'OSLastBootUpTime') { $SetValue = $ComputerOS.LastBootUpTime } elseif ($BuiltinValue -eq 'UserDNSDomain') { $SetValue = $env:USERDNSDOMAIN } elseif ($BuiltinValue -eq 'FQDN') { $SetValue = ((Get-CimInstance win32_computersystem).name + '.' + (Get-CimInstance win32_computersystem).domain).ToLower() } elseif ($BuiltinValue -eq 'IPv4Address') { $SetValue = (Get-NetIPConfiguration | Where-Object { $null -ne $_.IPv4DefaultGateway -and $_.NetAdapter.Status -ne "Disconnected" }).IPv4Address.IPAddress } elseif ($BuiltinValue -eq 'IPv6Address') { $SetValue = (Get-NetIPConfiguration | Where-Object { $null -ne $_.IPv4DefaultGateway -and $_.NetAdapter.Status -ne "Disconnected" }).IPv6Address.IPAddress } if ($Name) { $SetName = $Name } else { $SetName = $BuiltinValue } } else { $SetValue = $Value $SetName = $Name } [PSCustomObject] @{ Type = 'Values' Name = $SetName Value = $SetValue Color = $Color FontSize = $FontSize FontFamilyName = $FontFamilyName ValueColor = $ValueColor ValueFontSize = $ValueFontSize ValueFontFamilyName = $ValueFontFamilyName } } if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full").Release -lt 461808) { Write-Warning "This module requires .NET Framework 4.7.2 or later."; return } # Export functions and aliases as required Export-ModuleMember -Function @('New-BGInfo', 'New-BGInfoLabel', 'New-BGInfoValue') -Alias @() # SIG # Begin signature block # MIItqwYJKoZIhvcNAQcCoIItnDCCLZgCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBhgTmweMfHkmF6 # kkRxeVbKF3K0UUwtjgp0TpDsuTSleaCCJq4wggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggWQMIIDeKADAgECAhAFmxtXno4hMuI5B72nd3VcMA0GCSqG # SIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIw # aTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLK # EdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4Tm # dDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembu # d8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnD # eMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1 # XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVld # QnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTS # YW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSm # M9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzT # QRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6Kx # fgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD # VR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzANBgkq # hkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNkaA9Wz3eucPn9mkqZucl4 # XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjSPMFDQK4dUPVS/JA7u5iZ # aWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK7VB6fWIhCoDIc2bRoAVg # X+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eBcg3AFDLvMFkuruBx8lbk # apdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp5aPNoiBB19GcZNnqJqGL # FNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msgdDDS4Dk0EIUhFQEI6FUy # 3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vriRbgjU2wGb2dVf0a1TD9u # KFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ79ARj6e/CVABRoIoqyc54 # zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5nLGbsQAe79APT0JsyQq8 # 7kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3i0objwG2J5VT6LaJbVu8 # aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0HEEcRrYc9B9F1vM/zZn4w # ggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 # c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqG # SIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbS # g9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9 # /UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXn # HwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0 # VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4f # sbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40Nj # gHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0 # QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvv # mz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T # /jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk # 42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5r # mQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E # FgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5n # P+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcG # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNV # HSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIB # AH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxp # wc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIl # zpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQ # cAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfe # Kuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+j # Sbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJsh # IUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6 # OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDw # N7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR # 81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2 # VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGsDCCBJigAwIBAgIQ # CK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQGEwJVUzEV # MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t # MSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjEwNDI5MDAw # MDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBT # aWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zrPYGXcMW7xIUmMJ+k # jmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHMgQM+TXAkZLON4gh9 # NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8IrgnQnAZaf6mIBJNYc9 # URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyCEUhSaN4QvRRXXegY # E2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0p6MDDnSlrzm2q2AS # 4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQakhCBj7A7CdfHmzJa # wv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0XLyTRSiDNipmKF+w # c86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960IHnWmZcy740hQ83eR # Gv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2FKZbS110YU0/EpF2 # 3r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBHX8mBUHOFECMhWWCK # ZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q27IwyCQLMbDwMVhEC # AwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFGg34Ou2 # O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9P # MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB3BggrBgEFBQcB # AQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggr # BgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwHAYDVR0gBBUwEzAH # BgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIBADojRD2NCHbuj7w6 # mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6jfCbVN7w6XUhtldU/ # SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmImoqKwba9oUgYftzY # gBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtfJqGVWEjVGv7XJz/9 # kNF2ht0csGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrxoj7bQ7gzyE84FJKZ # 9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3LIU/Gs4m6Ri+kAew # Q3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx4b6cpwoG1iZnt5Lm # Tl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9Oj9FpsToFpFSi0HA # SIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+ICw2/O/TOHnuO77Xr # y7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug0wcCampAMEhLNKhR # ILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5Vzu0nAPthkX0tGFu # v2jiJmCG6sivqf6UHedjGzqGVnhOMIIGvDCCBKSgAwIBAgIQC65mvFq6f5WHxvnp # BOMzBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5 # NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAwMDAwMFoXDTM1MTEy # NTIzNTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERpZ2lDZXJ0MSAwHgYD # VQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQAD # ggIPADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjEiDtqmeOlwf0KMCBD # Er4IxHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOcRe8+CEJp+3R2O8oo # 76EO7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/GLoUb35SfWHh43rO # H3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0ChaV76Nhnj37DEYTX9R # eNZ8hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8UuKGn9966fR5X6kgX # j3o5WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHwSJ+QQRZ1fisD8UTV # DSupWJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4EfvFrpVNnes4c16J # idj5XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzIXp4P0wXkgNs+CO/C # acBqU0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3JyidxW48jwBqIJqImd93N # Rxvd1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizchNULpUEoA6Vva7b1X # CB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJcv6dQ4aEKOX5AgMB # AAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUB # Af8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1s # BwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFJ9X # LAN3DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1l # U3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZU # aW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAD2tHh92mVvjOIQS # R9lDkfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq3igpwrPvBmZdrlWB # b0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcHzBMutB6HzeledbDC # zFzUy34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTVOoJ4eTq7gj9UFAL1 # UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4Hv5swO+aAXxWUm3Wp # ByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgtd7/fvWTlCs30VAGE # sshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaidRJXrI+UzB6vAlk/8 # a1u7cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhdmm4bhYsVA6G2WgNF # YagLDBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dHPoWrUhftNpFC5H7Q # EY7MhKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDiCLg4D+TPVgKx2EgE # deoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7zcEO1xwcdcqJsyz/J # ceENc2Sg8h3KeFUCS7tpFk7CrDqkMIIHXzCCBUegAwIBAgIQB8JSdCgUotar/iTq # F+XdLjANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBT # aWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMDQxNjAwMDAwMFoX # DTI2MDcwNjIzNTk1OVowZzELMAkGA1UEBhMCUEwxEjAQBgNVBAcMCU1pa2/FgsOz # dzEhMB8GA1UECgwYUHJ6ZW15c8WCYXcgS8WCeXMgRVZPVEVDMSEwHwYDVQQDDBhQ # cnplbXlzxYJhdyBLxYJ5cyBFVk9URUMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQCUmgeXMQtIaKaSkKvbAt8GFZJ1ywOH8SwxlTus4McyrWmVOrRBVRQA # 8ApF9FaeobwmkZxvkxQTFLHKm+8knwomEUslca8CqSOI0YwELv5EwTVEh0C/Daeh # vxo6tkmNPF9/SP1KC3c0l1vO+M7vdNVGKQIQrhxq7EG0iezBZOAiukNdGVXRYOLn # 47V3qL5PwG/ou2alJ/vifIDad81qFb+QkUh02Jo24SMjWdKDytdrMXi0235CN4Rr # W+8gjfRJ+fKKjgMImbuceCsi9Iv1a66bUc9anAemObT4mF5U/yQBgAuAo3+jVB8w # iUd87kUQO0zJCF8vq2YrVOz8OJmMX8ggIsEEUZ3CZKD0hVc3dm7cWSAw8/FNzGNP # lAaIxzXX9qeD0EgaCLRkItA3t3eQW+IAXyS/9ZnnpFUoDvQGbK+Q4/bP0ib98XLf # QpxVGRu0cCV0Ng77DIkRF+IyR1PcwVAq+OzVU3vKeo25v/rntiXCmCxiW4oHYO28 # eSQ/eIAcnii+3uKDNZrI15P7VxDrkUIc6FtiSvOhwc3AzY+vEfivUkFKRqwvSSr4 # fCrrkk7z2Qe72Zwlw2EDRVHyy0fUVGO9QMuh6E3RwnJL96ip0alcmhKABGoIqSW0 # 5nXdCUbkXmhPCTT5naQDuZ1UkAXbZPShKjbPwzdXP2b8I9nQ89VSgQIDAQABo4IC # AzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYE # FHrxaiVZuDJxxEk15bLoMuFI5233MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAK # BggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEz # ODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5j # cmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3 # dy5kaWdpY2VydC5jb20vQ1BTMIGUBggrBgEFBQcBAQSBhzCBhDAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu # Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqGSIb3DQEB # CwUAA4ICAQC3EeHXUPhpe31K2DL43Hfh6qkvBHyR1RlD9lVIklcRCR50ZHzoWs6E # BlTFyohvkpclVCuRdQW33tS6vtKPOucpDDv4wsA+6zkJYI8fHouW6Tqa1W47YSrc # 5AOShIcJ9+NpNbKNGih3doSlcio2mUKCX5I/ZrzJBkQpJ0kYha/pUST2CbE3JroJ # f2vQWGUiI+J3LdiPNHmhO1l+zaQkSxv0cVDETMfQGZKKRVESZ6Fg61b0djvQSx51 # 0MdbxtKMjvS3ZtAytqnQHk1ipP+Rg+M5lFHrSkUlnpGa+f3nuQhxDb7N9E8hUVev # xALTrFifg8zhslVRH5/Df/CxlMKXC7op30/AyQsOQxHW1uNx3tG1DMgizpwBasrx # h6wa7iaA+Lp07q1I92eLhrYbtw3xC2vNIGdMdN7nd76yMIjdYnAn7r38wwtaJ3KY # D0QTl77EB8u/5cCs3ShZdDdyg4K7NoJl8iEHrbqtooAHOMLiJpiL2i9Yn8kQMB6/ # Q6RMO3IUPLuycB9o6DNiwQHf6Jt5oW7P09k5NxxBEmksxwNbmZvNQ65Zn3exUAKq # G+x31Egz5IZ4U/jPzRalElEIpS0rgrVg8R8pEOhd95mEzp5WERKFyXhe6nB6bSYH # v8clLAV0iMku308rpfjMiQkqS3LLzfUJ5OHqtKKQNMLxz9z185UCszGCBlMwggZP # AgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEw # PwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBSU0E0MDk2 # IFNIQTM4NCAyMDIxIENBMQIQB8JSdCgUotar/iTqF+XdLjANBglghkgBZQMEAgEF # AKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgor # BgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3 # DQEJBDEiBCCdPZGd5swJmKq1NRz5colGJb17MYZHWrhICg7tfpfguTANBgkqhkiG # 9w0BAQEFAASCAgBdB62fBkLGjMOpd8GEOlcUfoMQUaa2n3QoOTpdjXZ6upyEzyUv # SwxISryl1zehDToxKhwwkt/KzhG+CkV/eVU1bwiSw2mYFfW4DYNl0T51VnXjbc2O # yG6xB0jxb0exvCbqwRCX/0mOrAldGudDJ0tzgjoRTmfQnkJ9P4XPdbxNgEtmmeea # cid8Ce6awvmjveTYT10AIvGKIMOJc4Z8ednJIdZJmJnACYxWph+mSlZNPxwqmFe3 # Npqbi9pEawNPRkVEvUvGvD71Jn5nyhEiHqIRfewB6lEDwrLHFcEyFgJlHyjEbJ+/ # gyZTROAuc/9wBVj5dMSjavRVoj6MzsftVQhem29HZgDk2GMSlu53VUVcKix3UP6C # qolKX+S3DOzViK/Q1FupqMQfhNhk3XSvHMYmh3SppaT0++E2KfUfCxEW0DNYri3v # BCYKVc24xCibF9TLtaGD/Panys29gW7r0jcduq9rWhKH45njJgrLuTzvXUtf22Jc # hugNJPh/uw6WACet0y6sdjfAmAtprxodVw9k/v8TPR2txEJzp0dssU43fGDwsqHp # f4UQEZkMI64d8ooD128Az+1EzGYSxx/qrIhOupTIb/xq1RNRVwQdGJDI1RneAcFN # jrEFk4/JlkCxoTA3xNl5T6C+cYyMJmqA32qMUM3O9QEHKoLQiVEy0KlR0qGCAyAw # ggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYD # VQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBH # NCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAuuZrxaun+Vh8b56QTj # MwQwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwG # CSqGSIb3DQEJBTEPFw0yNDExMTkwODE5MjNaMC8GCSqGSIb3DQEJBDEiBCCWuGcL # GTaEokwyv/aFTDKACuoungGtFk8c+MXlRZ11hTANBgkqhkiG9w0BAQEFAASCAgBJ # ZXtQ+XIN3u1JNpqxQR2Sa1rVsh9bw/vdQuoFEGBZVgJJdasbsssMaZazd7ZYIA0I # fWBZx0J6wb7kQ1vOL896l0HKEQhW7wpJqcB14DzxFBeUgE9FLr3tN/KtzLFHfA6i # e4+FUP+dSk46yLmZlMILtiCOoxOgedEmpdzKbkLv54alImLQkf2wgUqf8fn2vtBv # wDIKTN8Rk1Hn1J4REXzXwdkDLIWXahMnjK1szy/EbywskAmpyk61lKlOC5uFv5ip # +5mNKQNJztiSxVs9OwgI5MCXUdfKzhtMNxPXfXsh2rGXw6UW74txHaCv6U5Lm4mb # 298q72vQ0yN/ImYmkI8Skwp8W7gXI8rvwo/9Om9a91hrg5ILs1zXNqe7AeeToNDN # H4Zf8qkmQx3WOsTjup+VKr8dMyC3Fs1O90+2F1zZJWx7ZkuREERi6dUAMadAoBAS # QARBRF/JY8wPIdZ9uXsd/fPOd/r1yVYXs5Sk+3fnox2lXdi+FdKr4qQ4rY5VYczx # LFThxoZDYbryxzlupm/Y03QGieI29wtWhToTPIJwCWP5maETu6h17L3iXbVLmPYH # XgnnT++Lw4/iyoReEEvOyw5T0lljTL8xXvQgpTBcoOkzQNgzfVlpnNE1EodYtKgo # WRIEjFXU1FyNwMXQUFpxU4vVCexQAVfznT326UM5GA== # SIG # End signature block |