布尔值 NoteProperty 变成一个数组
Boolean NoteProperty becomes an Array
标题说,当使用 Add-Member 或使用 splatting 分配给 NoteProperty 时,所有单个布尔值都会变成一个数组。
PS 版本:5.0.1xx
我遇到了一个奇怪的问题。我正在创建一个 PSObject,其中一个 NoteProperty 成员作为布尔值。该函数循环遍历一个列表,调用一个函数来执行计算,创建一个 object,然后将它添加到一个数组中。这似乎只发生在创建的第一个 object 上,但我没有在创建 5 个或更多 object 时对此进行测试。
我已经验证函数实际上返回布尔值并且分配给 属性 的变量是一个布尔值。
我的解决方法似乎很可靠,但我很好奇为什么会这样。
部分代码如下:
$clientCertsRequired = Get-Is-Client-Cert-Required -configFile $configFile -siteName $siteName
$httpsStatus = "Https is not enabled"
$clientCertStatus = "Client certs are not required"
if ($httpsEnabled -eq $true) {
$httpsStatus = "Https is enabled"
}
if ($clientCertsRequired -eq $true){
$clientCertStatus = "Client certs are required"
}
$sc = New-Object PSObject -Property @{
SiteName = $siteName;
ConfigFilePath = $path;
HttpsEnabled = $httpsStatus;
ClientCertStatus =$clientCertStatus;
ClientCertRequired = $clientCertsRequired;
}
# clean up of some inexplicable problem where assignment to property
# produces array with actual value in the last element.
if ($sc.ClientCertRequired.GetType().Name -eq "Object[]"){
$sc.ClientCertRequired = $sc.ClientCertRequired[-1]
}
$si += $sc
Function Get-Is-Client-Cert-Required{
param(
[xml]$configFile,
[string]$siteName
)
$functionName = $MyInvocation.MyCommand.Name
$clientCertRequired = $false
try{
# then read locations section (this will often not have any pages
$locationPath = "//configuration/location[@path='$siteName']"
[system.xml.xmlelement]$location = $configFile.DocumentElement.SelectSingleNode($locationPath)
if($location -ne $null){
[system.xml.xmlelement]$accessNode = $location.SelectSingleNode("system.webServer/security/access")
[system.xml.xmlelement]$authenticationNode = $location.SelectSingleNode("system.webServer/security/authentication")
[system.xml.xmlelement]$clientCertMappingNode
[system.xml.xmlelement]$iisClientCertMappingNode
[int]$sslFlagMask = 0
if($accessNode -ne $null){
$sslFlags = $accessNode.Attributes.GetNamedItem("sslFlags")
# $sslFlags = $accessNode.Attributes["sslFlags"].Value
if($sslFlagMask -ne $null){
$sslFlagMask = Convert-Ssl-Flag-String-To-Int-Flag -sslFlag $sslFlags.Value
}
}
if($authenticationNode -ne $null){
[system.xml.xmlelement]$clientCertMappingNode = $authenticationNode.SelectSingleNode("clientCertificateMappingAuthentication[@enabled='true']")
[system.xml.xmlelement]$iisClientCertMappingNode = $authenticationNode.SelectSingleNode("iisClientCertificateMappingAuthentication[@enabled='true']")
}
$clientCertAccepted = ($sslFlagMask -band $certAccepted) -eq $certAccepted
$clientCertRequired = Check-IIS-Express-SSL-Config $sslFlagMask
if($clientCertRequired -eq $false){
if($clientCertAccepted -and ($clientCertMappingNode -ne $null -or $iisClientCertMappingNode -ne $null)){
$clientCertRequired = $true
}
}
}
}catch{
$exceptionMessage = Get-Formatted-Exception-String -exceptionObject $_
$message = "$functionName - Exception`: $exceptionMessage"
Add-Exception -exception $message
Log-Error -message $message
}
$clientCertRequired
}
在 Get-Is-Client-Cert-Required
函数的主体中,您执行:
[system.xml.xmlelement]$clientCertMappingNode
[system.xml.xmlelement]$iisClientCertMappingNode
这个模式:
[type]$nonExistingVariable
在 PowerShell 中是一个糟糕的想法 - 与 C# 不同,PowerShell 没有裸变量声明的概念,上面的模式只是将 $null
强制转换为指定类型,如果它成功了 - 这可能是导致函数输出数组的原因。
如果您确实需要将变量绑定到特定类型,请在赋值时强制转换:
[type]$Variable = Get-Stuff
额外提示:函数和 cmdlet 的 PowerShell 惯用命名约定是 Noun-Verb
,只有一个连字符。该函数更合适的名称是:
Test-ClientCertRequirement
标题说,当使用 Add-Member 或使用 splatting 分配给 NoteProperty 时,所有单个布尔值都会变成一个数组。
PS 版本:5.0.1xx
我遇到了一个奇怪的问题。我正在创建一个 PSObject,其中一个 NoteProperty 成员作为布尔值。该函数循环遍历一个列表,调用一个函数来执行计算,创建一个 object,然后将它添加到一个数组中。这似乎只发生在创建的第一个 object 上,但我没有在创建 5 个或更多 object 时对此进行测试。
我已经验证函数实际上返回布尔值并且分配给 属性 的变量是一个布尔值。
我的解决方法似乎很可靠,但我很好奇为什么会这样。
部分代码如下:
$clientCertsRequired = Get-Is-Client-Cert-Required -configFile $configFile -siteName $siteName
$httpsStatus = "Https is not enabled"
$clientCertStatus = "Client certs are not required"
if ($httpsEnabled -eq $true) {
$httpsStatus = "Https is enabled"
}
if ($clientCertsRequired -eq $true){
$clientCertStatus = "Client certs are required"
}
$sc = New-Object PSObject -Property @{
SiteName = $siteName;
ConfigFilePath = $path;
HttpsEnabled = $httpsStatus;
ClientCertStatus =$clientCertStatus;
ClientCertRequired = $clientCertsRequired;
}
# clean up of some inexplicable problem where assignment to property
# produces array with actual value in the last element.
if ($sc.ClientCertRequired.GetType().Name -eq "Object[]"){
$sc.ClientCertRequired = $sc.ClientCertRequired[-1]
}
$si += $sc
Function Get-Is-Client-Cert-Required{
param(
[xml]$configFile,
[string]$siteName
)
$functionName = $MyInvocation.MyCommand.Name
$clientCertRequired = $false
try{
# then read locations section (this will often not have any pages
$locationPath = "//configuration/location[@path='$siteName']"
[system.xml.xmlelement]$location = $configFile.DocumentElement.SelectSingleNode($locationPath)
if($location -ne $null){
[system.xml.xmlelement]$accessNode = $location.SelectSingleNode("system.webServer/security/access")
[system.xml.xmlelement]$authenticationNode = $location.SelectSingleNode("system.webServer/security/authentication")
[system.xml.xmlelement]$clientCertMappingNode
[system.xml.xmlelement]$iisClientCertMappingNode
[int]$sslFlagMask = 0
if($accessNode -ne $null){
$sslFlags = $accessNode.Attributes.GetNamedItem("sslFlags")
# $sslFlags = $accessNode.Attributes["sslFlags"].Value
if($sslFlagMask -ne $null){
$sslFlagMask = Convert-Ssl-Flag-String-To-Int-Flag -sslFlag $sslFlags.Value
}
}
if($authenticationNode -ne $null){
[system.xml.xmlelement]$clientCertMappingNode = $authenticationNode.SelectSingleNode("clientCertificateMappingAuthentication[@enabled='true']")
[system.xml.xmlelement]$iisClientCertMappingNode = $authenticationNode.SelectSingleNode("iisClientCertificateMappingAuthentication[@enabled='true']")
}
$clientCertAccepted = ($sslFlagMask -band $certAccepted) -eq $certAccepted
$clientCertRequired = Check-IIS-Express-SSL-Config $sslFlagMask
if($clientCertRequired -eq $false){
if($clientCertAccepted -and ($clientCertMappingNode -ne $null -or $iisClientCertMappingNode -ne $null)){
$clientCertRequired = $true
}
}
}
}catch{
$exceptionMessage = Get-Formatted-Exception-String -exceptionObject $_
$message = "$functionName - Exception`: $exceptionMessage"
Add-Exception -exception $message
Log-Error -message $message
}
$clientCertRequired
}
在 Get-Is-Client-Cert-Required
函数的主体中,您执行:
[system.xml.xmlelement]$clientCertMappingNode
[system.xml.xmlelement]$iisClientCertMappingNode
这个模式:
[type]$nonExistingVariable
在 PowerShell 中是一个糟糕的想法 - 与 C# 不同,PowerShell 没有裸变量声明的概念,上面的模式只是将 $null
强制转换为指定类型,如果它成功了 - 这可能是导致函数输出数组的原因。
如果您确实需要将变量绑定到特定类型,请在赋值时强制转换:
[type]$Variable = Get-Stuff
额外提示:函数和 cmdlet 的 PowerShell 惯用命名约定是 Noun-Verb
,只有一个连字符。该函数更合适的名称是:
Test-ClientCertRequirement