【问题标题】:How to change powershell script output behavior如何更改 powershell 脚本输出行为
【发布时间】:2021-06-10 15:56:40
【问题描述】:

我不是脚本编写者,如果有人可以通过删除 UCPID 值但只保留 servername

来帮助我修改以下脚本

目前下面的脚本从 csv 文件中查找两列,现在我想将行为更改为仅查找 ServerName 因为现在 CSV 文件只有一列,其中仅在每一行中包含服务器并更新相关XML。

$data = Import-Csv .\MyFile.csv
$luTable = @{}

# Create Keys in Lookup Table
$data | % {
    if (!$luTable.ContainsKey("$($_.ServerName)")) { $luTable["$($_.UCPID)"] = New-Object System.Collections.ArrayList }
}

$luTable.Keys | % {
    $key = $_ # Store Key
    $data | where UCPID -Match $_ | select ServerName | % {
        $luTable[$key].Add($_.ServerName)
    }
}

# Build XML Files

$luTable.Keys | % {
    $key = $_

    $filetext = gc ".\MyXML.xml"
    $filetext = $filetext.Replace("#Title#", $key)

    $targets = ""
    
    $luTable[$key] | % {
        $targets += "<ComputerName>$($_)</ComputerName>"
    }

    $filetext = $filetext.Replace("#computername#", $targets)

    sc -Path ".\$($key).xml" -Value $filetext
}

我尝试删除下面的代码,但没有帮助。

# Create Keys in Lookup Table
    $data | % {
        if (!$luTable.ContainsKey("$($_.ServerName)")) { $luTable["$($_.UCPID)"] = New-Object System.Collections.ArrayList }
    }

//CSV文件内容

ServerName
Server1
Server2
Server3
Server4
Server5

//XML - 我想要复制服务器的位置

        <AnnounceOffer>false</AnnounceOffer>
            <OfferCategory>false</OfferCategory>
            <OfferDescriptionHTML>false</OfferDescriptionHTML>
        </SettingsLocks>
        <IsUrgent>false</IsUrgent>
        <Target>
            #computername#
        </Target>
    </SingleAction>
</BES>

#computername#必须替换为以下-

<ComputerName>Server1</ComputerName>
<ComputerName>Server2</ComputerName>
<ComputerName>Server3</ComputerName>
<ComputerName>Server4</ComputerName>

【问题讨论】:

  • 我很困惑...您说您的 CSV 只有一个名为“ServerName”的列,但您的代码示例尝试使用 CSV 中不存在的“UCPID”来执行操作,所以。 . 如果您只有一个服务器名称列表,为什么还需要查找表?它们如何与 xml 对应?请提供 CSV、XML 和所需输出的示例。
  • 这不是和How to change PowerShell result behavior based on XML & CSV? 类似吗?唯一不同的是CSV 现在包含标题UCPID 而不是IGPID,就像上一个问题一样?
  • 是的,西奥!它们看起来相同,但用于不同的项目。在这个当前脚本中,我不想查找任何内容,只想复制 ServerName 并将它们放入 XML 之间 - $($_),这一次它只是寻找服务器名称并只构建一个xml 基于此,之前使用 UCPID/IGPID 创建了多个 xml,现在只有一个。
  • @Theo 请查看更新信息并寻求帮助。

标签: powershell


【解决方案1】:

如果您的 XML 如下所示:

<BES>
    <SingleAction>
        <SettingsLocks>
            <AnnounceOffer>false</AnnounceOffer>
            <OfferCategory>false</OfferCategory>
            <OfferDescriptionHTML>false</OfferDescriptionHTML>
        </SettingsLocks>
        <IsUrgent>false</IsUrgent>
        <Target>
            #computername#
        </Target>
    </SingleAction>
</BES>

那么这里有两种选择:

方法一:使用PowerShell的XML功能

# load the xml from file
$xml= New-Object System.XML.XMLDocument
$xml.Load("D:\Test\MyXML.xml")

# select the node with the #computername# placeholder inside
$targetNode = $xml.SelectSingleNode('//BES/SingleAction/Target')
$targetNode.'#text' = ''  # remove the placeholder text

# read the servernames from file and create and insert new nodes for each of them
(Import-Csv -Path 'D:\Test\AllServers.csv').ServerName | 
  ForEach-Object { 
    $newNode = $xml.CreateElement('ComputerName')
    $newNode.InnerText = $_
    $targetNode.AppendChild($newNode)
  }

# save the updated XML
$xml.Save('D:\Test\NewXml.xml')

方法2:将xml视为纯文本,并对其进行简单的文本替换

# read the XML as multiline text
$xml = Get-Content -Path 'D:\Test\MyXML.xml' -Raw

# find the line where the #computername# placeholder is and get the indentation value
$indent = ' ' * ($xml | Select-String -Pattern '(?m)^(\s+)#computername#').Matches[0].Groups[1].Length

# read the servernames from file and construct a multiline string
$servers = ((Import-Csv -Path 'D:\Test\AllServers.csv').ServerName | 
             ForEach-Object { "$indent<ComputerName>$_</ComputerName>" }) -join [environment]::NewLine

# now replace in the xml and write to (new) file
$xml -replace "(?m)^$indent#computername#", $servers | Set-Content -Path 'D:\Test\NewXml.xml' -Encoding UTF8

两种情况的结果:

<BES>
    <SingleAction>
        <SettingsLocks>
            <AnnounceOffer>false</AnnounceOffer>
            <OfferCategory>false</OfferCategory>
            <OfferDescriptionHTML>false</OfferDescriptionHTML>
        </SettingsLocks>
        <IsUrgent>false</IsUrgent>
        <Target>
            <ComputerName>Server1</ComputerName>
            <ComputerName>Server2</ComputerName>
            <ComputerName>Server3</ComputerName>
            <ComputerName>Server4</ComputerName>
            <ComputerName>Server5</ComputerName>
        </Target>
    </SingleAction>
</BES>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 2013-03-10
    • 2014-03-23
    • 2017-01-31
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多