2017-02-14 88 views
0

我创建了一个脚本来遍历我们的用户目录并修改和XML文档以更改应用程序中的设置。通常当我使用foreach它会使我的变量=集合中的一个项目。相反,这个脚本将所有从$XMLPaths到我的$Path变量。使用Powershell使用Foreach修改多个XML文档

$XMLPaths = Get-ChildItem \\DFSRoot\DFSShare\view\Profiles\*\AppData\Roaming\Trillian\ -Recurse -Force | 
      Where-Object {$_.Name -contains 'Events.xml'} | 
      Select FullName | 
      FT -HideTableHeaders | 
      Out-String 

foreach ($Path in $XMLPaths) { 
    $xml = [xml](Get-Content $Path) 
    $node = $xml.events.prefs.setting | Where {$_.Name -eq 'Sounds'} 
    $node.value = '1' 
    $XML.Save($Path) 
    $Path 
    $node 
} 

这是我使用的XML文档。

<?xml version="1.0" encoding="utf-8" ?> 
    <!DOCTYPE events 
     PUBLIC "--//IETF//DTD RFCxxxx XEVENTS 1.0//EN" "xevents.dtd"> 

<!-- WARNING: This is a generated file by Trillian. Do not update while --> 
<!--   Trillian is running otherwise updates will be erased  --> 

    <events> 
     <version>1.0</version> 
     <Prefs> 
      <setting name="idle" value="1"/> 
      <setting name="sounds" value="1"/> 
      <setting name="sounds_away" value="1"/> 
      <setting name="sounds_suppress" value="1"/> 
      <setting name="automatic_outbound" value="1"/> 
      <setting name="hide_disabled" value="1"/> 
      <setting name="video_capture" value="1"/> 
      <setting name="buzz_sound" value="1"/> 
      <setting name="game_status" value="0"/> 
      <setting name="awaymessage_song" value="0"/> 
      <setting name="awaymessage_autosave" value="1"/> 
      <setting name="awaymessage_update2" value="1"/> 
      <setting name="away_autoresponse" value="0"/> 
     </Prefs> 
     <AwayList> 
      <AwayGroup name="Root"> 
       <AwayMessage label="Set%20all%20Do%20Not%20Disturb" text="" awayState="1" awayMenu="1" autoRespond="0" system="1"> 
        <Status medium="ASTRA" type="Do%20Not%20Disturb"/> 
       </AwayMessage> 
       <AwayMessage label="Set%20all%20Offline" text="" awayState="1" awayMenu="0" autoRespond="1" system="1"> 
        <Status medium="ASTRA" type="Offline"/> 
       </AwayMessage> 
       <AwayMessage label="Set%20all%20Away" text="Away%20since%20%25time%25%20%28%25timeZoneOffset%25%29" awayState="1" awayMenu="1" autoRespond="1" system="1"> 
        <Status medium="ASTRA" type="Away"/> 
       </AwayMessage> 
       <AwayMessage label="Set%20all%20Invisible" text="" awayState="1" awayMenu="1" autoRespond="0" system="1"> 
        <Status medium="ASTRA" type="Invisible"/> 
       </AwayMessage> 
       <AwayMessage label="Set%20all%20Back" text="" awayState="0" awayMenu="1" autoRespond="0" system="1"> 
        <Status medium="ASTRA" type="Online"/> 
       </AwayMessage> 
       <AwayMessage label="Set%20all%20Idle" text="Idle%20since%20%25time%25%20%28%25timeZoneOffset%25%29" awayState="1" awayMenu="0" autoRespond="1" system="1"> 
        <Status medium="ASTRA" type="Away"/> 
       </AwayMessage> 
      </AwayGroup> 
     </AwayList> 
    </events> 

变量$Path这应该只有在它一个目录在一个时间,而不是有这样的吧。

\\DFSROOT\DFSSHare\view\Profiles\User1\AppData\Roaming\Trillian\users\User1\Events.xml 
\\DFSROOT\DFSSHare\view\Profiles\User2\AppData\Roaming\Trillian\users\User2\Events.xml 
\\DFSROOT\DFSSHare\view\Profiles\User3\AppData\Roaming\Trillian\users\User3\Events.xml 
\\DFSROOT\DFSSHare\view\Profiles\User4\AppData\Roaming\Trillian\users\User4\Events.xml 
\\DFSROOT\DFSSHare\view\Profiles\User5\AppData\Roaming\Trillian\users\User5\Events.xml
+0

不要使用'Format-Table'作为流水线中的中间步骤。 – PetSerAl

+0

也不要使用'Out-String',除非你真的打算把结果作为一个字符串。 –

回答

0

的问题在于,你得到的$XMLPaths变量是,而不是一个阵列。因此,您的ForEach表达式将变量$XMLPaths解释为一个元素的数组,其中一个元素是一个包含连接在一起的所有路径的字符串。

您可以随时通过输入$Variable.GetType()来检查变量$Variable的类型。例如,当我跑你的第一行代码,这是我所看到的:

PS > $XMLPaths.GetType() 

IsPublic IsSerial Name BaseType 
-------- -------- ---- -------- 
True  True  String System.Object 

尝试用这种替代第一行:

#Remote Computers 
$XMLPaths = (Get-ChildItem \\DFSRoot\DFS Share\view\Profiles\*\AppData\Roaming\Trillian\ -Recurse -Force | Where-Object {$_.Name -contains 'Events.xml'} | Select FullName).FullName 

Select FullName条款后,包含对象的数组返回物业FullName。所以通过调用.FullName,它返回一个文件名的数组。

你应该能够检查$XMLPaths是数组类型:

PS > $XMLPaths.GetType() 

IsPublic IsSerial Name  BaseType 
-------- -------- ----  -------- 
True  True  Object[] System.Array 
0

$XMLPaths.GetType().Name回报String。使用

$auxiliaryPath = "\\DFSRoot\DFS Share\view\Profiles\*\AppData\Roaming\Trillian" 
$XMLPaths = (Get-ChildItem "$auxiliaryPath\Events.xml" -Recurse -Force).FullName