2017-02-14 89 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