问题
I have a task to make changes to some Config files in a Directory, and the files that need changing are 7, all starting with "Monitoring_Tran_xx".
Within these files there are certain values (TransactionID="01" AgreedResponseTime="500" SearchProfileID="216") that need changing but not present across all 7, and will need to check if they are present before replace or creating them.
Also I am trying to insert a new parameter(using new-item) if a certain parameter is equal to a certain value e.g. if TemplateType = "4152" then create a new parameter next to it "DirectoryPoolID = '3' "
I will appreciate your help on this please.
Thanks
Example of Config file below:
<?xml *version="1.0"* ?>
<Monitor>
<Configuration OperatingMode="Transaction" LogFileName="C:\Program Files\*******s\MonitoringOMTR\MonitorLog_01.log" WriteFileInterval="120" ConnectionKey="**********" />
<TransactionMonitoringConfig TransactionID="01" AgreedResponseTime="500" SearchProfileID="216" />
<ShowMessages>
<Message Name="MOISearchStart" />
<Message Name="MOOSearchFound" />
<Message Name="MOOSearchEnd" />
<Message Name="MOOAlert" />
</ShowMessages>
<PerformanceCounters TransactionCount="191" TransactionBreaches="0" />
</Monitor>
Powershell script that i tried but it didn't quite result well:
(Get-Content -Path '***FS2072\UserData$\aroyet01\Desktop\HostPS.txt') |
if ([bool]((Get-Content -Path "***FS2072\UserData$\aroyet01\Desktop\HostPS.txt") -like '*DirectoryPool*', '*SearchProfile*')) {
write-host "Found it"
}
else {
write-host "Did not find it"
}
ForEach-Object {$_ -replace 'TransactionCount="191"', 'TransactionCount="196"'} |
Set-Content -Path '***FS2072\UserData$\aroyet01\Desktop\HostPS.txt'
Get-Content -Path '***FS2072\UserData$\aroyet01\Desktop\HostPS.txt'
回答1:
I have a task to make changes to some Config files in a Directory, and the files that need changing are 7, all starting with "Monitoring_Tran_xx".
Stop treating your XML files as raw text - they can be parsed and treated with much better precision :)
First up, we need to parse the document(s) as XML, the easiest way probably being:
$xmlDocument = [xml](Get-Content C:\Path\To\)
Since you have multiple documents with a common naming pattern, we might use Get-ChildItem to discover the files on disk and loop over them to get the paths:
Get-ChildItem -Path C:\path\to\config\files\Monitoring_Tran_*.ps1 |ForEach-Object {
# read each document from disk with `Get-Content`, convert to [xml]
$xmlDocument = [xml]($_ |Get-Content)
}
Next, we need to be able to navigate our XML document. PowerShell has native syntax bindings for this:
$tmConfig = $xmlDocument.Monitor.TransactionMonitoringConfig
or, you can use XPath expressions to navigate the document as well:
$tmConfig = $xmlDocument.SelectSingleNode("/Monitor/TransactionMonitoringConfig")
Within these files there are certain values (
TransactionID="01" AgreedResponseTime="500" SearchProfileID="216") that need changing but not present across all 7, and will need to check if they are present before replace or creating them
To check whether a named attribute exists on a node we can use the HasAttribute() method:
if($tmConfig.HasAttribute('TransactionID')){
# attribute exists, let's update it!
$tmConfig.SetAttribute('TransactionID', 123) # replace 123 with whatever ID you need
}
Also I am trying to insert a new parameter(using new-item) if a certain parameter is equal to a certain value e.g. if
TemplateType = "4152"then create a new parameter next to it"DirectoryPoolID = '3' "
In the case where you want to add a new attribute to a node only if another attribute has a specific value, you can use GetAttribute() and SetAttribute():
if($xmlNode.GetAttribute('TemplateType') -eq "4152"){
$xmlNode.SetAttribute("DirectoryPoolID", 3)
}
Whenever you're done, save the document back to file:
Get-ChildItem -Path C:\path\to\config\files\Monitoring_Tran_*.ps1 |ForEach-Object {
# read each document from disk with `Get-Content`, convert to [xml]
$xmlDocument = [xml]($_ |Get-Content)
<# write all the code to inspect and update the attributes here #>
# write document back to disk
$xmlDocument.Save($_.FullName)
}
回答2:
Looking at your code snippet i can only assist by giving you the advice to start with basic Powershell syntax documentation.
help about_If
help about_Pipelines
To give you an idea... Your if is placed in a pipeline. Your ForEach-Object is not placed in a pipeline. Both of these don't work the way you posted it. You can start from something like this:
$Content = '***FS2072\UserData$\aroyet01\Desktop\HostPS.txt'
if ($Content -condition 'Yourcondition') {
$Content | ForEach-Object {
$_ -replace 'Regex', 'Replacement'
}
} else {
'Your else here'
}
For editing the xml file you can take a look at this post as hinted by vonPryz in this question today.
来源:https://stackoverflow.com/questions/63470287/trying-to-combine-replace-and-new-item-in-powershell