在 Powershell 中获取第一个元素的属性
Get first element's attribute in Powershell
我正在编写一个自动站点备份 powershell 脚本。
我在从 appcmd.exe 获得的 [xml] 强制转换变量中有以下 xml:
<application path="/" applicationPool="komplus.ua-PROD">
<virtualDirectoryDefaults />
<virtualDirectory path="/" physicalPath="C:\WEB\PROD\komplus.ua" />
</application>
<application path="/kb" applicationPool="komplus.ua-PROD" enabledProtocols="http, https">
<virtualDirectoryDefaults />
<virtualDirectory path="/" physicalPath="C:\WEB\PROD\komplus.ua\kb" />
</application>
xml在变量$xml中输入。
我需要获取第一个应用程序元素中 VirtualDirectory 元素的 physicalPath 属性的值。
我尝试了多种选择,包括自定义 Get-XmlElement 函数,但似乎无法获取值。
目前我有:
$selectResult = $xmlInput.application.virtualDirectory | Select physicalPath
但是$selectResult 为空。
请协助解析出我需要的值是正确的
更新
这是我用来获取完整路径的完整函数:
function GetPhysicalPath ([String]$siteName) {
function Get-PipelineInput
{
end {
$inputAsVar = 'Current input is:' + $input
write-host "##teamcity[message text='$inputAsVar']"
write-host "##teamcity[message text='About to cast to xml']"
$xmlInput = [xml]@"<root>$input</root>"@
write-host "##teamcity[message text='Cast to xml finished.']"
$selectResult = $xml.root.Application | Where-Object { $_.path -eq '/' } | ForEach-Object { $_.virtualDirectory.physicalPath }
write-host "##teamcity[message text='$selectResult']"
return $selectResult
#$node = Get-XmlNode -XmlDocument $xmlInput -NodePath "application.virtualDirectory"
#$nodeAsVar = 'Single node is:' + $node
#write-host "##teamcity[message text='$nodeAsVar']"
#if ($node -eq $null) { return $null }
#return $node.physicalPath
}
}
$appCmd = "$Env:SystemRoot\system32\inetsrv\appcmd.exe"
return & $appCmd list app /site.name:"$siteName" /config | Get-PipelineInput
}
您的 xml 无效。 XML 需要根元素。如果您的 "xml"-file 丢失了它,那么您可以像这样将文件的内容自己包装在根元素中:
Get-ChildItem -Path C:\Users\Frode\Desktop -Filter "appcmd*" | ForEach-Object {
#Wrap "xml" in root element and convert to xml-type
$xml = [xml]@"
<root>
$([System.IO.File]::ReadAllText($_.FullName))
</root>
"@
#Get first physicalPath
$xml.root.Application[0].virtualDirectory.physicalPath
}
C:\WEB\PROD\komplus.ua
如果您有 PowerShell 3 或更新版本,您可以将 $([System.IO.File]::ReadAllText($_.FullName))
替换为更友好的 $(Get-Content -Path $_.FullName -Raw))
。但是,ReadAllText()
通常更快,所以我还是会使用它。
如果您想要根应用程序,您可能应该搜索它而不是猜测它是第一个元素。你可以尝试这样的事情:
Get-ChildItem -Path C:\Users\Frode\Desktop -Filter "appcmd*" | ForEach-Object {
#Wrap "xml" in root element and convert to xml-type
$xml = [xml]@"
<root>
$(Get-Content -Path $_.FullName -Raw))
</root>
"@
#Get root app's physicalPath
$xml.root.Application | Where-Object { $_.path -eq '/' } | ForEach-Object { $_.virtualDirectory.physicalPath }
}
如果您直接从 appcmd.exe 获取 xml-content(存储在变量中),则修改如下:
$outputfromappcmd = appcmd.exe something something
#Wrap "xml" in root element and convert to xml-type
$xml = [xml]"<root>$outputfromappcmd </root>"
#Get first physicalPath
$xml.root.Application | Where-Object { $_.path -eq '/' } | ForEach-Object { $_.virtualDirectory.physicalPath }
我正在编写一个自动站点备份 powershell 脚本。
我在从 appcmd.exe 获得的 [xml] 强制转换变量中有以下 xml:
<application path="/" applicationPool="komplus.ua-PROD">
<virtualDirectoryDefaults />
<virtualDirectory path="/" physicalPath="C:\WEB\PROD\komplus.ua" />
</application>
<application path="/kb" applicationPool="komplus.ua-PROD" enabledProtocols="http, https">
<virtualDirectoryDefaults />
<virtualDirectory path="/" physicalPath="C:\WEB\PROD\komplus.ua\kb" />
</application>
xml在变量$xml中输入。
我需要获取第一个应用程序元素中 VirtualDirectory 元素的 physicalPath 属性的值。
我尝试了多种选择,包括自定义 Get-XmlElement 函数,但似乎无法获取值。
目前我有:
$selectResult = $xmlInput.application.virtualDirectory | Select physicalPath
但是$selectResult 为空。
请协助解析出我需要的值是正确的
更新
这是我用来获取完整路径的完整函数:
function GetPhysicalPath ([String]$siteName) {
function Get-PipelineInput
{
end {
$inputAsVar = 'Current input is:' + $input
write-host "##teamcity[message text='$inputAsVar']"
write-host "##teamcity[message text='About to cast to xml']"
$xmlInput = [xml]@"<root>$input</root>"@
write-host "##teamcity[message text='Cast to xml finished.']"
$selectResult = $xml.root.Application | Where-Object { $_.path -eq '/' } | ForEach-Object { $_.virtualDirectory.physicalPath }
write-host "##teamcity[message text='$selectResult']"
return $selectResult
#$node = Get-XmlNode -XmlDocument $xmlInput -NodePath "application.virtualDirectory"
#$nodeAsVar = 'Single node is:' + $node
#write-host "##teamcity[message text='$nodeAsVar']"
#if ($node -eq $null) { return $null }
#return $node.physicalPath
}
}
$appCmd = "$Env:SystemRoot\system32\inetsrv\appcmd.exe"
return & $appCmd list app /site.name:"$siteName" /config | Get-PipelineInput
}
您的 xml 无效。 XML 需要根元素。如果您的 "xml"-file 丢失了它,那么您可以像这样将文件的内容自己包装在根元素中:
Get-ChildItem -Path C:\Users\Frode\Desktop -Filter "appcmd*" | ForEach-Object {
#Wrap "xml" in root element and convert to xml-type
$xml = [xml]@"
<root>
$([System.IO.File]::ReadAllText($_.FullName))
</root>
"@
#Get first physicalPath
$xml.root.Application[0].virtualDirectory.physicalPath
}
C:\WEB\PROD\komplus.ua
如果您有 PowerShell 3 或更新版本,您可以将 $([System.IO.File]::ReadAllText($_.FullName))
替换为更友好的 $(Get-Content -Path $_.FullName -Raw))
。但是,ReadAllText()
通常更快,所以我还是会使用它。
如果您想要根应用程序,您可能应该搜索它而不是猜测它是第一个元素。你可以尝试这样的事情:
Get-ChildItem -Path C:\Users\Frode\Desktop -Filter "appcmd*" | ForEach-Object {
#Wrap "xml" in root element and convert to xml-type
$xml = [xml]@"
<root>
$(Get-Content -Path $_.FullName -Raw))
</root>
"@
#Get root app's physicalPath
$xml.root.Application | Where-Object { $_.path -eq '/' } | ForEach-Object { $_.virtualDirectory.physicalPath }
}
如果您直接从 appcmd.exe 获取 xml-content(存储在变量中),则修改如下:
$outputfromappcmd = appcmd.exe something something
#Wrap "xml" in root element and convert to xml-type
$xml = [xml]"<root>$outputfromappcmd </root>"
#Get first physicalPath
$xml.root.Application | Where-Object { $_.path -eq '/' } | ForEach-Object { $_.virtualDirectory.physicalPath }