需要Powershell帮助写入Machine.config文件

5

PowerShell和Machine.config帮助

我对PowerShell非常陌生,如果可能的话,需要快速帮助(我相信这是一个普遍的句子)。我正在编写一个脚本来优化服务器以成为Web服务器,我需要使用PowerShell编写到machine.configs。我已经有了所有所需的优化,不需要在这方面提供帮助。

我已经试图解决了一个月,也进行了很多谷歌搜索,但我实在找不到解决方案,所以我想来请教专家们。希望我能够在PowerShell方面变得更加优秀,并在某些时候做出贡献。

到目前为止,我已经走得很远,并且已经完成了所有的优化和大部分的PowerShell,但是在脚本的1个部分卡住了。

  1. 我需要获取机器有多少CPU核心,我有这行代码

    $property = "numberOfCores" Get-WmiObject -class win32_processor -Property $property | Select-Object -Propert $property

这告诉我有几个核心,这正是我需要的,但一旦我知道了机器有多少核心,我需要写入一些值到machine.config中。

在system.web下,它有这些值

<system.web>
    <processModel autoConfig="true"/>

我需要用下面列出的值覆盖已有的值。
<system.web>
    <processModel maxWorkerThreads="370" maxIoThreads="370" minWorkerThreads="50" minIoThreads="50"/>
<httpRuntime minFreeThreads="90" minLocalRequestFreeThreads="80"/>

除了我无法弄清楚如何编写那行代码之外,我需要将minfreethreads乘以CPU核心数,并将该值写入90的位置,minLocalRequestFreeThreads 80同理。

例如,如果计算看到2个核心,它会编写以下行:

<processModel maxWorkerThreads="370" maxIoThreads="370" minWorkerThreads="50" minIoThreads="50"/>
<httpRuntime minFreeThreads="180" minLocalRequestFreeThreads="160"/>

之后,我需要添加。
<system.net>
<connectionManagement>
<add address = "*" maxconnection = "200" />
</connectionManagement>
</system.net>

如之前所述,将200替换为CPU核心数与200相乘的值。希望这不会太难做到,我不知道如何编写XML文件,然后还要将核心数乘以该值并添加到那里。

因此,它应该像这样:

<system.net>
<connectionManagement>
<add address = "*" maxconnection = "400" />
</connectionManagement>
</system.net>

有人能帮我一下吗?

编辑 1/4

这是我目前的代码,虽然还有很长的路要走,但我正在逐行进行编写,因此某些部分可能无法正常工作,但我认为我走在了正确的道路上。

$xml = New-Object XML
$xml.Load("C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\machine.config")
$Path = "C:\Windows\Microsoft.Net\Framework\V2.0.50727\config"
$File = "machine.config"
$current_path = $path + "\" + $file
$text = (get-content ($current_path))
$xml = [XML] (get-content ($current_path))
$p.RemoveAttribute("autoConfig")
$p = $xml.configuration."system.web".processModel
$p.SetAttribute("maxWorkerThreads", "370")
$p.SetAttribute("maxIoThreads", "370")
$p.SetAttribute("minWorkerThreads", "50")
$p = $xml.configuration."system.web".httpRunTime
$p.SetAttribute("minFreeThreads", "90")
$p.SetAttribute("minLocalRequestFreeThreads", "80")
$processor = (Get-CimInstance Win32_processor -Property NumberOfLogicalProcessors | Select -ExpandProperty "NumberOfLogicalProcessors")
$minFT = $processor * 90
$minFT = [string]$minFT
$minFT * 2
$p.SetAttribute("minFreeThreads", [string]$minFT)

$xml_content = [xml]@'
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "200" />
    </connectionManagement>
  </system.net>
'@

编辑 1/11

实际上失败了,并显示以下消息:

方法调用失败,因为[System.Object []]不包含名为“op_Multiply”的方法。 位于C:\Install\Pre4.ps1的124个字符处: +$httpRuntimexml.setAttribute("minFreeThreads",90 * $numberOfCores) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation:(op_Multiply:String)[],RuntimeException + FullyQualifiedErrorId : MethodNotFound

方法调用失败,因为[System.Object []]不包含名为“op_Multiply”的方法。 位于C:\Install\Pre4.ps1的125个字符处: +$httpRuntimexml.setAttribute("minLocalRequestFreeThreads",80 * $numberOfCores) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation:(op_Multiply:String)[],RuntimeException + FullyQualifiedErrorId : MethodNotFound

方法调用失败,因为[System.Object []]不包含名为“op_Multiply”的方法。 位于C:\Install\Pre4.ps1的130个字符处: + + ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation:(op_Multiply:String)[],RuntimeException + FullyQualifiedErrorId : MethodNotFound

----- 脚本 ------

$numberOfCores = Get-WmiObject -class win32_processor numberOfCores | Select-Object -ExpandProperty numberOfCores
$path = "c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config"
[xml]$machineConfig = Get-Content $path
$node = $machineConfig.SelectNodes("/configuration/system.web") 
$node.RemoveChild(($node.SelectSingleNode("processModel"))) | Out-Null
$processModelxml = $machineConfig.CreateElement("processModel")
$processModelxml.setAttribute("maxWorkerThreads",370)
$processModelxml.setAttribute("maxWorkerThreads",370)
$processModelxml.setAttribute("maxIoThreads",370)
$processModelxml.setAttribute("minWorkerThreads",50)
$processModelxml.setAttribute("minIoThreads",50)
$node.AppendChild($processModelxml) | Out-Null
$httpRuntimexml = $machineConfig.CreateElement("httpRuntime")
$httpRuntimexml.setAttribute("minFreeThreads",90 * $numberOfCores)
$httpRuntimexml.setAttribute("minLocalRequestFreeThreads",80 * $numberOfCores)
$node.AppendChild($httpRuntimexml) | Out-Null
[xml]$systemnetxml = @"
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "$(200 * $numberOfCores)" />
    </connectionManagement>
  </system.net>
"@
$machineConfig.configuration.AppendChild($machineConfig.ImportNode($systemnetxml."system.net",$true)) | Out-Null
$machineConfig.Save("c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config")

是的,虽然可能不是百分之百的工作状态,但我已经取得了很大进展,只是还不完美。 - Iggy Castillo
1
将其添加到问题中,我们可以在此基础上进行构建 :) - Matt
哦,它把所有东西都搞砸了,我该怎么修复它?对不起,这不是我的代码看起来的样子。 - Iggy Castillo
谢谢Matt,如果这有帮助,请告诉我,现在已经成为问题的一部分,作为编辑添加。 - Iggy Castillo
是的,如果没有其他人尝试过,我可以考虑今天看一下它。 - Matt
显示剩余16条评论
1个回答

2

我没有太多接触XML和PowerShell,但这似乎可以满足你的需求。将文件作为XML加载。删除两个有问题的元素,以便我们可以按照我们想要的方式构建它们。最后,我们在配置元素下添加元素和相应的详细信息。

如果在提交之前值被乘以,则会看到涵盖该操作的多个乘法实例。在你的示例中,你对一个字符串进行了乘法运算,这只会将其复制。考虑以下两个例子。

PS C:\Users\mcameron> "200" * 2
200200

PS C:\Users\mcameron> 200 * 2
400

根据您的需要更改路径。最后,我会将其写入临时位置。我建议您进行测试时也这样做。

$numberOfCores = Get-WmiObject -class win32_processor numberOfCores | Select-Object -ExpandProperty numberOfCores


$path = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machineTest.config"
[xml]$machineConfig = Get-Content $path

# Remove the elements we are going to be replacing
$node = $machineConfig.SelectNodes("/configuration/system.web") 
$node.RemoveChild(($node.SelectSingleNode("processModel"))) | Out-Null

# Create the element processModel and set attributes
$processModelxml = $machineConfig.CreateElement("processModel")
$processModelxml.setAttribute("maxWorkerThreads",370)
$processModelxml.setAttribute("maxWorkerThreads",370)
$processModelxml.setAttribute("maxIoThreads",370)
$processModelxml.setAttribute("minWorkerThreads",50)
$processModelxml.setAttribute("minIoThreads",50)
$node.AppendChild($processModelxml) | Out-Null

# Create the element httpRuntime and set attributes. Adjust values based on number of cores
$httpRuntimexml = $machineConfig.CreateElement("httpRuntime")
$httpRuntimexml.setAttribute("minFreeThreads",(90 * $numberOfCores))
$httpRuntimexml.setAttribute("minLocalRequestFreeThreads",(80 * $numberOfCores))
$node.AppendChild($httpRuntimexml) | Out-Null

# Build the <system.net> section
[xml]$systemnetxml = @"
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "$(200 * $numberOfCores)" />
    </connectionManagement>
  </system.net>
"@

# Import into config
$machineConfig.configuration.AppendChild($machineConfig.ImportNode($systemnetxml."system.net",$true)) | Out-Null

# Save changes
$machineConfig.Save("c:\temp\testing.xml")
# Change back to $path to write back to original file.

你还会看到 Out-Null,它的作用是抑制正在创建的元素的输出。它不会改变文件的处理方式。


顺便说一下,我不能使用以下代码:$numberOfCores = Get-WmiObject -class win32_processor numberOfCores | Select-Object -ExpandProperty numberOfCores因为这会给我主机的总核心数,我需要客户机的核心数,因为这将在虚拟机上运行,这就是为什么我运行以下代码:$processor = (Get-CimInstance Win32_processor -Property NumberOfLogicalProcessors | Select -ExpandProperty "NumberOfLogicalProcessors")听起来没问题吧? - Iggy Castillo
@IggyCastillo 我并没有深入研究这将如何运行以及针对哪台机器。但是,是的,这就是你要做的事情。 - Matt
嘿,马特,这行代码出错了:“[xml]$systemnetxml = @” - Iggy Castillo
PS H:> [xml]$systemnetxml = @在第一行的字符22处:
  • [xml]$systemnetxml = @
  • ~
源文本中有无法识别的标记。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnrecognizedToken
- Iggy Castillo
你在那个@符号后面有一个双引号吗? - Matt
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接