Вывод PowerShell в формате XML
у меня возникли проблемы с получением желаемых результатов в правильном формате с этим PowerShell запрос при запуске с XML-файлом, экспортированным из Планировщик Задач. В конце концов, я буду работать против всех Планировщик Задач экспортированные задания сбрасываются в один и тот же XML-файл, но я начинаю только с одного.
PowerShell Logic (не работает)
$file = "C:foldertest.xml"
$Xml = [xml](Get-Content $file)
$Xml.SelectNodes("//*").ChildNodes | Select URI,Command |
Where-Object { ($_.URI -ne $null) -or ($_.Command -ne $null) } | FL
возможно, есть лучше или более явный способ сделать это с PowerShell в цикле или встраивании некоторых C# код и выполнение этого с помощью PowerShell и т. д. Я решил, что спрошу других здесь, так как я не могу понять это после тонны тестирования и исследований, но я открыт для всех идей, чтобы помочь мне получить желаемый результат или что-то подобное (см. ниже). Если мне нужен результат SQL Server Я хотел бы использовать FOR XML PATH
.
Текущий Формат Результата (не нужные)
URI : _TestTest
Command :
URI :
Command : C:Folderprocess1.exe
URI :
Command : C:Folderprocess2.exe
Желаемый Формат Результата (или похожие)
URI : _TestTest
Command : C:Folderprocess1.exe
Command : C:Folderprocess2.exe
пример XML
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2017-03-09T09:36:56.2658334</Date>
<Author>FBI-PC1User</Author>
<URI>_TestTest</URI>
</RegistrationInfo>
<Triggers />
<Principals>
<Principal id="Author">
<UserId>S-1-5-21-3517161704-4063526634-2635523359-1001</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>C:Folderprocess1.exe</Command>
</Exec>
<Exec>
<Command>C:Folderprocess2.exe</Command>
</Exec>
</Actions>
</Task>
Технические Характеристики Системы (должен работать)
- Windows 7
- PowerShell V 4.0
2 ответов
поскольку вы выбираете оба объекта вместе, применяя условие where, поэтому для поддержания равенства в качестве одного объекта он отображается так .
в вашем случае вы можете сохранить результат в arraylist и делать манипуляции там для всех команды что вы получаете, как :
$file = "C:\folder\test.xml"
$Xml = [xml](Get-Content $file)
$URI= $Xml.SelectNodes("//*").ChildNodes | Select URI| Where-Object { $_.URI -ne $null}
$Command= $Xml.SelectNodes("//*").ChildNodes | Select Command| Where-Object { $_.Command -ne $null}
$arraylisttable = New-Object System.Collections.ArrayList
$arraylisttable.Add($URI) | Out-Null
foreach($cmd in $Command)
{
$arraylisttable.Add($Cmd) | Out-Null
}
$arraylisttable | fl
выход:
надеюсь, что это помогает.
$Xml.SelectNodes("//*[local-name()='Command' or local-name()='URI']") | select Name, "#text"
Name #text
---- -----
URI \_Test\Test
Command C:\Folder\process1.exe
Command C:\Folder\process2.exe
таким образом, вы перемещаете логику выбора в Xpath. Вещи, чтобы отметить:
-
//*
выбирает все узлы - текст
[]
является критерием фильтра XPath. - используя
local-name()
функции XPath-это трюк, чтобы избежать возни с пространствами имен
обратите внимание, что сравнения XPath чувствительны к регистру. К сожалению XPath 1.0 не имеет lower-case()
или как функция. Чтобы сделать сравнение без учета регистра (как PowerShell ли) использовать translate()
функция:
$Xml.SelectNodes("//*[translate(local-name(), 'COMAND', 'comand')='command' or translate(local-name(), 'uri', 'URI')='URI']") | select Name, "#text"
если вы предпочитаете чистый Powershell над XPath, вот альтернативное решение:
$xml.SelectNodes('//*') | ? {$_.Name -in ('command', 'uri')} | select Name, "#text"
еще одно задачи. Вы не должны dump них. Они изначально находятся как xml уже вC:\Windows\Tasks
или
C:\Windows\System32\Tasks
папки в зависимости от ОС. Для Win7 это C:\Windows\System32\Tasks
. Вам понадобится доступ администратора, чтобы прочитать их.
Edit: и ровно то же вывод:
$xml.SelectNodes('//*') | ? { $_.Name -in ('command', 'uri') } |
select Name, @{Name = 'Value'; Expression = {": $($_.'#text')" } } |
ft -HideTableHeaders
URI : \_Test\Test
Command : C:\Folder\process1.exe
Command : C:\Folder\process2.exe
настраиваемого объекта:
$customObject = [pscustomObject]@{
URI = ($xml.SelectNodes("//*[local-name()='URI']")).'#text'
Command = ($xml.SelectNodes("//*[local-name()='Command']")).'#text'
}
$customObject | fl
URI : \_Test\Test
Command : {C:\Folder\process1.exe, C:\Folder\process2.exe}