Powershell을 사용하여 웹 서버에서 IIS 바인딩을 설정하고 있으며 다음 코드에 문제가 있습니다.
$serverIps = gwmi Win32_NetworkAdapterConfiguration
| Where { $_.IPAddress }
| Select -Expand IPAddress
| Where { $_ -like '*.*.*.*' }
| Sort
if ($serverIps.length -le 1) {
Write-Host "You need at least 2 IP addresses for this to work!"
exit
}
$primaryIp = $serverIps[0]
$secondaryIp = $serverIps[1]
서버에 2 개 이상의 IP가있는 경우 괜찮습니다. Powershell이 배열을 반환하고 배열 길이를 쿼리하고 첫 번째와 두 번째 주소를 잘 추출 할 수 있습니다.
문제는-IP가 하나만있는 경우 Powershell이 단일 요소 배열을 반환하지 않고 IP 주소 ( “192.168.0.100”과 같은 문자열)를 반환합니다. 문자열에 .length
속성이 있으므로 1보다 큽니다. 테스트를 통과하고 컬렉션의 처음 두 IP 주소 대신 문자열의 처음 두 문자로 끝납니다.
Powershell에서 단일 요소 컬렉션을 반환하도록 강제하거나 반환 된 “사물”이 컬렉션이 아닌 개체인지 여부를 어떻게 확인할 수 있습니까?
답변
두 가지 방법 중 하나로 변수를 배열로 정의하십시오.
파이프 명령을 @
시작 부분 에 괄호로 묶습니다 .
$serverIps = @(gwmi Win32_NetworkAdapterConfiguration
| Where { $_.IPAddress }
| Select -Expand IPAddress
| Where { $_ -like '*.*.*.*' }
| Sort)
변수의 데이터 유형을 배열로 지정하십시오.
[array]$serverIps = gwmi Win32_NetworkAdapterConfiguration
| Where { $_.IPAddress }
| Select -Expand IPAddress
| Where { $_ -like '*.*.*.*' }
| Sort
또는 변수의 데이터 유형을 확인하십시오 …
IF ($ServerIps -isnot [array])
{ <error message> }
ELSE
{ <proceed> }
답변
Count 속성을 가질 수 있도록 결과를 배열에 강제로 적용합니다. 단일 객체 (스칼라)에는 Count 속성이 없습니다. 문자열에는 길이 속성이 있으므로 잘못된 결과를 얻을 수 있으므로 Count 속성을 사용하십시오.
if (@($serverIps).Count -le 1)...
그런데 문자열과 일치 할 수있는 와일드 카드를 사용하는 대신 -as 연산자를 사용하세요.
[array]$serverIps = gwmi Win32_NetworkAdapterConfiguration -filter "IPEnabled=TRUE" | Select-Object -ExpandProperty IPAddress | Where-Object {($_ -as [ipaddress]).AddressFamily -eq 'InterNetwork'}
답변
변수를 미리 배열로 선언하면 하나라도 요소를 추가 할 수 있습니다.
이것은 작동합니다 …
$serverIps = @()
gwmi Win32_NetworkAdapterConfiguration
| Where { $_.IPAddress }
| Select -Expand IPAddress
| Where { $_ -like '*.*.*.*' }
| Sort | ForEach-Object{$serverIps += $_}
답변
Measure-Object
개체의 Count
속성에 의존하지 않고 실제 개체 수를 가져 오는 데 사용할 수 있습니다 .
$serverIps = gwmi Win32_NetworkAdapterConfiguration
| Where { $_.IPAddress }
| Select -Expand IPAddress
| Where { $_ -like '*.*.*.*' }
| Sort
if (($serverIps | Measure).Count -le 1) {
Write-Host "You need at least 2 IP addresses for this to work!"
exit
}
답변
,
반환 목록 앞에 쉼표 ( ) 를 추가 return ,$list
하거나 목록을 캐스트 [Array]
하거나 [YourType[]]
목록을 사용하는 위치에 추가 할 수 있습니다.
답변
배열을 Azure 배포 템플릿에 전달하는 데이 문제가 발생했습니다. 하나의 개체가있는 경우 PowerShell은이를 문자열로 “변환”했습니다. 아래 예에서는 $a
태그 값에 따라 VM 객체를 가져 오는 함수에서 반환됩니다. 를 래핑 $a
하여 New-AzureRmResourceGroupDeployment
cmdlet에 전달합니다 @()
. 이렇게 :
$TemplateParameterObject=@{
VMObject=@($a)
}
New-AzureRmResourceGroupDeployment -ResourceGroupName $RG -Name "TestVmByRole" -Mode Incremental -DeploymentDebugLogLevel All -TemplateFile $templatePath -TemplateParameterObject $TemplateParameterObject -verbose
VMObject
템플릿의 매개 변수 중 하나입니다.
이를 수행하는 가장 기술적이고 강력한 방법은 아니지만 Azure에는 충분합니다.
최신 정보
위의 내용이 작동했습니다. 위와 일부를 모두 시도했지만 $vmObject
배포 템플릿과 호환되는 배열 로 전달 하고 하나의 요소를 사용 하는 유일한 방법 은 다음과 같습니다. 2015 년 버그)) :
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
foreach($vmObject in $vmObjects)
{
#$vmTemplateObject = $vmObject
$asJson = (ConvertTo-Json -InputObject $vmObject -Depth 10 -Verbose) #-replace '\s',''
$DeserializedJson = (New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer -Property @{MaxJsonLength=67108864}).DeserializeObject($asJson)
}
$vmObjects
Get-AzureRmVM의 출력입니다.
I 패스 $DeserializedJson
(Array 형의) 배치 템플릿 ‘파라미터.
참고로 멋진 오류 New-AzureRmResourceGroupDeployment
는 다음과 같습니다.
"The template output '{output_name}' is not valid: The language expression property 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Expression.Expressions.JTokenExpression'
can't be evaluated.."
답변
참조 된 객체로 반환하므로 전달하는 동안 변환되지 않습니다.
return @{ Value = @("single data") }