【问题标题】:Prevent Powershell XML file updates from sending output to command line?防止 Powershell XML 文件更新将输出发送到命令行?
【发布时间】:2020-12-03 02:26:19
【问题描述】:

我在网上找到了这个函数,它根据我从 CSV 文件中提供的值更新 IIS web.config XML 文件。我想防止在执行函数时打印每个 XML 条目修改的输出。我已经尝试了很多次来使用 Out-Null,但我似乎无法找到这个 XML 更新函数的哪个部分导致了输出。

我想删除“为 D:\Inetpub\WWWRoot\test 设置 web.config appSettings”行之后的所有 XML 更新输出,如下所示。输出似乎是函数从 CSV 文件中读取并更新 web.config 文件的键/值对。

为 D:\Inetpub\WWWRoot\test 设置 web.config appSettings #文本 ----- allowFrame TRUE

authenticationType SSO

cacheProviderType 共享

这是我正在使用的功能:

function Set-Webconfig-AppSettings
{
    param (
        # Physical path for the IIS Endpoint on the machine without the "web.config" part.
        # Example: 'D:\inetpub\wwwroot\cmweb510\'
        [parameter(mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String] $path,
 
        # web.config key that you want to create or change
        [parameter(mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String] $key,
 
        # Value of the key you want to create or change
        [parameter(mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String] $value
    )
 
   Write-Host "Setting web.config appSettings for $path" -ForegroundColor DarkCyan
 
    $webconfig = Join-Path $path "web.config"
    [bool] $found = $false
 
    if (Test-Path $webconfig)
    {
        $xml = [xml](get-content $webconfig);
        $root = $xml.get_DocumentElement();
 
        foreach ($item in $root.appSettings.add)
        {
            if ($item.key -eq $key)
            {
                $item.value = $value;
                $found = $true;
            }
        }
 
        if (-not $found)
        {
            
            $newElement = $xml.CreateElement("add");
            $nameAtt1 = $xml.CreateAttribute("key")
            $nameAtt1.psbase.value = $key;
            $newElement.SetAttributeNode($nameAtt1);
 
            $nameAtt2 = $xml.CreateAttribute("value");
            $nameAtt2.psbase.value = $value;
            $newElement.SetAttributeNode($nameAtt2);
 
            $xml.configuration["appSettings"].AppendChild($newElement);
        }
        
        $xml.Save($webconfig)
    }
    else
    {
        Write-Error -Message "Error: File not found '$webconfig'"
    }
}

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

    SetAttributeNode 和 AppendChild 都输出信息所以我们只需要$null[void] 那些输出

    function Set-Webconfig-AppSettings
    {
        param (
            # Physical path for the IIS Endpoint on the machine without the "web.config" part.
            # Example: 'D:\inetpub\wwwroot\cmweb510\'
            [parameter(mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [String] $path,
    
            # web.config key that you want to create or change
            [parameter(mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [String] $key,
    
            # Value of the key you want to create or change
            [parameter(mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [String] $value
        )
    
       Write-Host "Setting web.config appSettings for $path" -ForegroundColor DarkCyan
    
        $webconfig = Join-Path $path "web.config"
        [bool] $found = $false
    
        if (Test-Path $webconfig)
        {
            $xml = [xml](get-content $webconfig);
            $root = $xml.get_DocumentElement();
    
            foreach ($item in $root.appSettings.add)
            {
                if ($item.key -eq $key)
                {
                    $item.value = $value;
                    $found = $true;
                }
            }
    
            if (-not $found)
            {
            
                $newElement = $xml.CreateElement("add");
                $nameAtt1 = $xml.CreateAttribute("key")
                $nameAtt1.psbase.value = $key;
                $null = $newElement.SetAttributeNode($nameAtt1);
    
                $nameAtt2 = $xml.CreateAttribute("value");
                $nameAtt2.psbase.value = $value;
                $null = $newElement.SetAttributeNode($nameAtt2);
    
                $null = $xml.configuration["appSettings"].AppendChild($newElement);
            }
        
            $xml.Save($webconfig)
        }
        else
        {
            Write-Error -Message "Error: File not found '$webconfig'"
        }
    }
    

    【讨论】:

      【解决方案2】:

      在 PowerShell 中,从 .NET 方法返回值(通常是所有输出)既不分配给变量,也不通过管道发送到另一个命令,也不重定向到文件 是从函数隐式输出(“返回”) - 即使没有明确的输出命令,例如 Write-Outputreturn 语句。
      请参阅this answer 的底部部分,了解此隐式输出功能背后的基本原理。

      因此,在 PowerShell 中:

      • 当您调用 .NET 方法时,您需要了解它们是否返回值(从技术上讲,不返回值由返回类型 @987654330 表示@)。
      • 如果他们这样做并且如果您不需要此返回值,您必须明确丢弃(抑制)它,以便它不会意外成为函数输出的一部分。

      在您的情况下,是对 System.Xml.XmlElement.SetAttributeNodeSystem.Xml.XmlElement.AppendChild 方法的调用导致了您的问题,因为它们具有您没有抑制的返回值。

      Doug Maurer's helpful answer 展示了如何通过将方法调用分配给$null ($null = ...)来丢弃这些返回值。

      虽然也存在其他两种抑制输出的方法 - 投射到[void] 和管道到Out-Null - $null = ...最佳的整体选择,如this answer 中所述。

      【讨论】:

      • 谢谢,如果我有声望的话,我会投赞成票的。
      猜你喜欢
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 2012-02-25
      • 2011-12-14
      • 1970-01-01
      • 2012-08-29
      • 2011-04-23
      • 2011-06-27
      相关资源
      最近更新 更多