将多个XML转换为PowerShell,提取信息,然后使用信息

时间:2016-12-13 16:25:59

标签: xml powershell

我遇到了将多个XML导入Powershell,提取我需要的信息然后使用这些信息的问题。这是我导入我的XML的交易很好​​,信息是正确的并且输出但我不知道还有什么办法将信息导出到CSV或只是使用信息来更新ARS(AD)中的属性。< / p>

cls
$filePath = dir("c:\Users\*.xml")
foreach ($f in $filePath){
$xml = [Xml] (Get-Content $f)
$xml.myFields.Employee | Select-Object Acct.EmployeeId
}

我得到的输出是正确的,但如果我要放:

$test = $xml.myFields.Employee | Select-Object Acct.EmployeeId

使用这个我得到@ {Acct.EmployeeID = matt}的值,我无法通过Get-Qaduser管道它,我无法将其导出到csv,因为它只是覆盖了所有内容而我离开了最后的XML文档信息。如果我将export-csv放在括号内侧或外侧,也会发生同样的事情。

我理解这可能是一个新手问题,但我刚刚开始,任何帮助将不胜感激。

提前致谢。

<my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    <my:Employee>
        <my:Acct.Action>XXXX</my:Acct.Action>
        <my:Acct.Eff_date>XXXX</my:Acct.Eff_date>
        <my:Acct.E_last>XXXX</my:Acct.E_last>
        <my:Acct.E_first>XXXX</my:Acct.E_first>
        <my:Acct.E_init>XXXX</my:Acct.E_init>
        <my:Acct.E_title>XXXX</my:Acct.E_title>
        <my:Acct.E_dept>XXXX</my:Acct.E_dept>
        <my:Acct.E_phext>XXXX</my:Acct.E_phext>
        <my:Acct.Rep_phext></my:Acct.Rep_phext>
        <my:Acct.Same_last></my:Acct.Same_last>
        <my:Acct.Same_first></my:Acct.Same_first>
        <my:Acct.Action_tip></my:Acct.Action_tip>
        <my:Acct.Rep_display></my:Acct.Rep_display>
        <my:Acct.EmployeeID>XXXX</my:Acct.EmployeeID>
        <my:Acct.Email>XXXX</my:Acct.Email>
        <my:EmployeeContractor>
    </my:Employee>

最后一个问题(发表在评论中):

$users = Get-Content -Raw -Path "c:\Users\*.xml"
| ForEach-Object { ([xml] $_).myFields.Employee.'Acct.EmployeeID' } |   
export-csv c:\Users\mattheww\Desktop\test.csv -NoTypeInformation

或者

$users = Get-Content -Raw -Path "c:\Users\*.xml"
| ForEach-Object { ([xml] $_).myFields.Employee.'Acct.EmployeeID' }
foreach ($user in $users) {
Get-qaduser -SamAccountName $user | select firstname}

1 个答案:

答案 0 :(得分:1)

尝试以下方法:

Get-Content -Raw -Path c:\Users\*.xml | 
  ForEach-Object { ([xml] $_).myFields.Employee.'Acct.EmployeeID' }

此代码还简化了您的方法:

  • 而不是Get-ChildItemdir是别名)/ Get-Content组合,单个Get-Content电话就足够了;请注意包含-Raw,以确保每个文件都作为包含整个内容的单个字符串返回。

  • 包含输入文件内容的字符串通过管道发送,并由ForEach-Object cmdlet逐个处理:

    • ([xml] $_)只是将手头的文件内容强制转换为XML文档($_(或$PSItem)是引用当前管道输入对象的自动变量。 / p>

    • myFields.Employee.'Acct.EmployeeID'然后深入到XML文档中以提取感兴趣的值(这意味着输出)。

      • 请注意'Acct.EmployeeID'中对周围引号的需要,以便区分使用.深入到层次结构并访问 name 碰巧的属性包括.

将员工ID保存在变量$users中,同时将其汇总到Get-QADUser

Get-Content -Raw -Path c:\Users\*.xml | 
  ForEach-Object -ov users { ([xml] $_).myFields.Employee.'Acct.EmployeeID' } |
    ForEach-Object { Get-qaduser -SamAccountName $_ | Select-Object firstname }

感谢-ov user(简称:-OutVariable user),$user接收由(第一个)ForEach-Object电话创建的所有员工ID的数组。

虽然原则上你可以转而使用Export-Csv,但仅使用字符串这样做是没有意义的,因为Export-Csv会产生输入对象的列名称,类型[string]只有.Length属性,因此您的CSV文件只包含字符串 length

因此,你可以

  • 使用Set-Content / Out-File按原样编写字符串,

  • 或将整个员工对象发送至Export-Csv,只需省略.'Acct.EmployeeId'部分:

Get-Content -Raw -Path c:\Users\*.xml | 
  ForEach-Object -ov users { ([xml] $_).myFields.Employee } | 
    Export-Csv -NoTypeInformation ~\Desktop\test.csv

请注意,使用包含ForeEach-Object cmdlet (或其内置别名%)的管道通常可以提供比{{1}更优雅的解决方案} 循环(虽然后一种结构通常更快)。

至于你的代码:

foreach返回带有Select-Object 属性自定义对象,其中包含感兴趣的值:

  • Acct.EmployeeId string 上下文中该对象的样子。
  • 相比之下,当输出到控制台时,PowerShell的有用默认格式为您提供了看起来的内容,就像一样兴趣,但标题 @{Acct.EmployeeID=matt}(带有Acct.EmployeeId下划线)的存在表明具有名为--- 的属性的对象是输出。
  • 如果对输出的类型有疑问,请输入Acct.EmployeeId

... | Get-Member恰好起作用,但暗示了对PS语法的误解:您使用的是.NET方法语法,而PS cmdlet使用参数语法(如传统shell中) ,所以编写命令最好如下:

dir("c:\Users\*.xml")

或者,依赖于Get-ChildItem -Path "c:\Users\*.xml" 隐含地是第一个位置参数的事实,并且引用此特定路径不是必需的:

-Path

如果它们包含在PowerShell中具有特殊含义的字符,则只需引用字符串参数(在参数模式下);需要注意的是,与Get-ChildItem c:\Users\*.xml

相比,有更多不同的角色
cmd.exe

您可以通过<space> " # & ' ( ) , ; < > @ ` { | } (可扩展字符串),"..."(字符串文字)或引用(转义)各个字符来引用。使用'...'(反引号;也可以在`内使用);要在"..."内嵌入',请使用'...'