Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing to Machine.config using Powershell assistance required

Powershell and Machine.config help

I am very new to powershell and I need a quick hand if at all possible (I am sure this is a common sentence). I am writing a script that optimizes a server to become a webserver, I need to write to the machine.configs using powershell. I also have all of the Optimizations needed, I don't need help no that part.

I have been trying to figure it out for over a month, lots of googling as well, I cant really find a solution, so I figured to come to the experts. Hopefully i can get good in powershell too and contribute at some point.

I have gotten incredibly far so far and have already done all of the optimizations and most of the powershell but am stuck on 1 part in the script

  1. I need to get how many cpu cores the machine has, I have this line

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

That tells me how many cores i have, which is exactly what I need but Once I have how many cores the machine has, I need to write to the machine.config some values.

Under system.web, it has these values

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

I would need to overwrite the already present value with this listed below

<system.web>
    <processModel maxWorkerThreads="370" maxIoThreads="370" minWorkerThreads="50" minIoThreads="50"/>
<httpRuntime minFreeThreads="90" minLocalRequestFreeThreads="80"/>

Aside from writing that line there (which I cant figure out how to do), I need to multiply the minfreethreads by the number of CPU cores and write that value in the place of the 90 and the same for minLocalRequestFreeThreads 80

So for example, if the computation sees 2 cores it would write the following lines

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

after that, I need to add

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

As before, then replace the 200 with the multiplied values of the cpu cores and the 200. I hope that's not too much to ask, I don't know how to write to xml files, and then also multiply the cores and take that value and add it there?

so it would like this

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

Can anyone give me a hand?

Edit 1/4

This is the code i have so far, I am very far, I am working on it line by line so somethings may not work but I think I am on the right path

$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>
'@

Edit 1/11

Actually it failed, with the message

Method invocation failed because [System.Object[]] does not contain a method named 'op_Multiply'. At C:\Install\Pre4.ps1:124 char:1 + $httpRuntimexml.setAttribute("minFreeThreads",90 * $numberOfCores) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (op_Multiply:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound

Method invocation failed because [System.Object[]] does not contain a method named 'op_Multiply'. At C:\Install\Pre4.ps1:125 char:1 + $httpRuntimexml.setAttribute("minLocalRequestFreeThreads",80 * $numberOfCores) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (op_Multiply:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound

Method invocation failed because [System.Object[]] does not contain a method named 'op_Multiply'. At C:\Install\Pre4.ps1:130 char:45 + + ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (op_Multiply:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound

----- script ------

$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")
like image 731
Iggy Castillo Avatar asked Oct 30 '22 12:10

Iggy Castillo


1 Answers

Havent played with XML and PowerShell much but this seems to work for what you want. Load the file as an XML. Remove the two elements in question so that we can build them as we want. Lastly we add the element and corresponding details under the configuration element.

In the case of values being multiplied before committed you will see several instances of multiplication that cover that. In your example you were performation multiplication on a string which would have simply duplicated it. Consider the two following examples.

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

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

Change your paths as you see fit. You will see at the end I write to a temporary location. I urge you to do the same for testing.

$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.

You will also see Out-Null which is there to suppress the output of the elements being created. It does not change what happens to the file.

like image 95
Matt Avatar answered Nov 15 '22 07:11

Matt