Powershell command -- To add a attribute if not exist in a particular node of a XML - string

<APPPOOL APPPOOL.NAME="Classic" RuntimeVersion="v2.0" state="Started">
<add name="Classic" autoStart="true" managedRuntimeVersion="v2.0">
<APPPOOL APPPOOL.NAME="GetServiceDet" RuntimeVersion="v2.0" state="Started">
<add name="GetServiceDet" autoStart="true">
my file has many line begining with word "add name".
I want to check if these lines have a string "managedRuntimeVersion".
if not exists, then i need to add managedRuntimeVersion="v2.0" to
that line.
Expected Result as below
<APPPOOL APPPOOL.NAME="Classic" RuntimeVersion="v2.0" state="Started">
<add name="Classic" autoStart="true" managedRuntimeVersion="v2.0">
<APPPOOL APPPOOL.NAME="GetServiceDet" RuntimeVersion="v2.0" state="Started">
<add name="GetServiceDet" autoStart="true" managedRuntimeVersion="v2.0">
I have tried with the below script.. but in the result.. it is given only the lines having "add name"
$sfile="C:\Users\subash.s\Desktop\backup\pool.xml"
(((gc "$sfile") | Select-String -Pattern "add name" |
select-string -notmatch "managedRuntimeVersion") -replace '>',' managedRuntimeVersion="v2.0">') |
Set-Content "$sfile"
with the above script. i got below result..
<add name="Classic" autoStart="true" managedRuntimeVersion="v2.0">
<add name="GetServiceDet" autoStart="true" managedRuntimeVersion="v2.0">

For Pete's sake, the configuration file is XML, not a text file! Edit it as an XML document, and you will save a lot of headaches.
There are a few ways to add attributes into such a document. As the XML in the question is a fragment - and of illegal syntax, the sample code uses a bit modified version of the same. Select all add nodes that don't have got managedRuntimeVersion attribute, create one and add attribute with values to the nodes. Like so,
# Dummy data for testing
[xml]$x = #'
<root>
<APPPOOL APPPOOL.NAME="GetServiceDet" RuntimeVersion="v2.0" state="Started">
<add name="GetServiceDet2" autoStart="true"/>
</APPPOOL>
<APPPOOL APPPOOL.NAME="Classic" RuntimeVersion="v2.0" state="Started">
<add name="Classic" autoStart="true" managedRuntimeVersion="v2.0" />
</APPPOOL>
<APPPOOL APPPOOL.NAME="GetServiceDet" RuntimeVersion="v2.0" state="Started">
<add name="GetServiceDet" autoStart="true"/>
</APPPOOL>
</root>
'#
# Select all add elements that don't have managedRuntimeVersion attribute
$nl=$x.SelectNodes('/root/APPPOOL/add[not(#managedRuntimeVersion)]')
# Add attributes to the elements
foreach($n in $nl) {
# Create new attribute and assign a value
$a = $x.CreateAttribute('managedRuntimeVersion')
$a.Value = 'v2.0'
[void]$n.Attributes.Append($a)
}
# Print modified version to console
$x.save([console]::out)
# Output
<?xml version="1.0" encoding="ibm850"?>
<root>
<APPPOOL APPPOOL.NAME="GetServiceDet" RuntimeVersion="v2.0" state="Started">
<add name="GetServiceDet2" autoStart="true" />
</APPPOOL>
<APPPOOL APPPOOL.NAME="Classic" RuntimeVersion="v2.0" state="Started">
<add name="Classic" autoStart="true" managedRuntimeVersion="v2.0" />
</APPPOOL>
<APPPOOL APPPOOL.NAME="GetServiceDet" RuntimeVersion="v2.0" state="Started">
<add name="GetServiceDet" autoStart="true" managedRuntimeVersion="v2.0" />
</APPPOOL>
</root>
Reading the actual file and saving changes to disk are left as an exercise to the reader.

Related

find xml-nodes by tag with wildcard

I am trying to find any nodes in a xml whos tags start with a certain pattern.
<data>
<general>
<va value="400" /> <!--looking for this "v-tag"-->
<vb value="42" /> <!-- and this one-->
<y value="43" />
</general>
<special>
<va value="100" />
</special>
</data>
I cannot put together the xpath expression. Something like this
xyz = lxml.etree.parse( ... )
vees = xyz.xpath("general/[tag='v*']")
I would like to have vees beeing
vees
Out[64]: [<Element va at 0x....>, <Element vb at 0x...>]
Try changing:
vees = xyz.xpath("general/[tag='v*']")
to
doc.xpath('//general//*[starts-with(name(),"v")]')
and see if it works.

Parsing XML for sub children using using python

I am trying to parse the below XML to get the following data. There are multiple rules following, I have shared only one rule below. Is it possible to parse the XML for these values?
name from section header, rule id value, applied-to name, source names, source values, destination name, destination value.
<?xml version="1.0" encoding="UTF-8"?>
<filteredfirewallConfiguration timestamp="1621338984151">
<contextId>globalroot</contextId>
<layer3Sections>
<section id="asdfsdf" name="production" generationNumber="132" timestamp="1621930404081" managedBy="universalroot-0" tcpStrict="false" stateless="false" useSid="false" type="LAYER3">
<rule id="1213213" disabled="false" logged="true" managedBy="universalroot-0">
<name>From Conversion Server</name>
<action>allow</action>
<appliedToList>
<appliedTo>
<name>re-int-dx</name>
<value>universalwire</value>
<type>VirtualWire</type>
<isValid>true</isValid>
</appliedTo>
<appliedTo>
<name>re-ext-ap</name>
<value>universalwire</value>
<type>VirtualWire</type>
<isValid>true</isValid>
</appliedTo>
</appliedToList>
<sectionId>sfsdfafee</sectionId>
<sources excluded="false">
<source>
<name>sdfsdf101</name>
<value>ipset-werfwefdc</value>
<type>IPSet</type>
<isValid>true</isValid>
</source>
<source>
<name>sdfsfdf102</name>
<value>ipset-4wsetgfreds</value>
<type>IPSet</type>
<isValid>true</isValid>
</source>
</sources>
<destinations excluded="false">
<destination>
<name>production-database-cluster</name>
<value>sg</value>
<type>SecurityGroup</type>
<isValid>true</isValid>
</destination>
<destination>
<name>newname</name>
<value></value>
<type>IPSet</type>
<isValid>true</isValid>
</destination>
</destinations>
<services>
<service>
<name>servicenwe</name>
<value>application-dgfsdfg</value>
<type>Application</type>
<isValid>true</isValid>
</service>
</services>
<direction>inout</direction>
<packetType>any</packetType>
</rule>
sofar, I have been able to get the section header only.
import requests
import xml.etree.ElementTree as ET
tree = ET.parse("out.xml")
root = tree.getroot()
for child in root.find('./layer3Sections'):
print(child.tag, child.attrib)

Replacing dynamic variables using REGEX content as variable in Azure CD Pipeline Powershell Task

I'm writing custom Powershell Azure CD Pipeline task(for VM) where my web.config should be replaced with pipeline variables. I have sample config file as with WebService and AuditService defined in my Azure CD pipeline variables.
<client>
<endpoint address="__WebService__" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="WebServiceClient.ServiceSoap" name="NLSService" />
<endpoint address="__AuditService__" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Audit" contract="AuditApiService.Audit" name="AuditService" />
</client>
I have powershell script as
$zipfileName = "$(System.DefaultWorkingDirectory)\_WebService-CI\drop\Service.zip"
$fileToEdit = "web.config"
$reg = [regex] '__(.*?)__'
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zip = [System.IO.Compression.ZipFile]::Open($zipfileName,"Update")
$configFile = $zip.Entries.Where({$_.name -like $fileToEdit})
# Read the contents of the file
$desiredFile = [System.IO.StreamReader]($configFile).Open()
$text = $desiredFile.ReadToEnd()
$desiredFile.Close()
$desiredFile.Dispose()
$text = $text -replace $reg, $(${1}) -join "`r`n"
#update file with new content
$desiredFile = [System.IO.StreamWriter]($configFile).Open()
$desiredFile.BaseStream.SetLength(0)
# Insert the $text to the file and close
$desiredFile.Write($text)
$desiredFile.Flush()
$desiredFile.Close()
# Write the changes and close the zip file
$zip.Dispose()
So how do I can replace dynamically Regex content within "__" and treat that content as a variable which should look into pipeline variables and replace it in line :
$text = $text -replace $reg, $(${1}) -join "rn"
If you can't use Replace Tokens or Transform Web.config file, here is something :
According to the fact that web.config file contains :
<?xml version="1.0" encoding="utf-8"?>
<!--
For ...
-->
<configuration>
..
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="checkVatBinding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="__WebService__" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="WebServiceClient.ServiceSoap" name="NLSService" />
<endpoint address="__AuditService__" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Audit" contract="AuditApiService.Audit" name="AuditService" />
</client>
</system.serviceModel>
</configuration>
You can try the following :
# Get all the file in a single var in spite of an array
$data = Get-Content "D:\temp\web.config" -raw
$reg = [Regex]::new( '__(.*?)__', [System.Text.RegularExpressions.RegexOptions]::Singleline)
# Here are the vars with the final values
$WebService = "http://Aurillac.fr"
$AuditService = "http://Cantal.fr"
# Here is how to replace
$reg.replace($data, {param ($p);return (Get-Variable -Name $p.groups[1]).Value})
Explanations :
The -raw in Get-Content allows to get all the characters in a single string
I use the .NET RegEx class with the option Singleline to allow search accross cariage return line feed (perhaps not necessary)
I use the Regex Replace method with a MatchEvaluator Delegate method translated in PowerShell by a Scriptblock to get the variable with the name catched by the RegEx.
It gives :
<?xml version="1.0" encoding="utf-8"?>
<!--
For ...
-->
<configuration>
..
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="checkVatBinding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://Aurillac.fr" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="WebServiceClient.ServiceSoap" name="NLSService" />
<endpoint address="http://Cantal.fr" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Audit" contract="AuditApiService.Audit" name="AuditService" />
</client>
</system.serviceModel>
</configuration>
Is there any reason you can't use the Replace Tokens task from the marketplace? This is my go-to for replacing values in config files.
https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens

with vimgrep - or other vim possibility - how can i get groups of data out of a file?

I'm trying to do a vimgrep on a file in order to get only two attributs with their values out of the xml file.
so far i can get the complete lines and i'd like with the help of groups to have a better display.
:vimgrep key= % | copen
^ I'd like to add to this command the grouping possibility with "( )" ....but without success for the moment.
i'd appreciate your help in order to have a result as explained in the "result expected"
part of the file that I'm working with :
<policy name="Menu_Controls" class="User" displayName="$(string.Menu_Controls)" explainText="$(string.IE_ExplainMenu_Controls)" presentation="$(presentation.Menu_Controls)" key="Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls">
<parentCategory ref="AdminApproved" />
<supportedOn ref="SUPPORTED_IE5" />
<elements>
<boolean id="MCSiMenu" valueName="{275E2FE0-7486-11D0-89D6-00A0C90C9B67}">
<trueValue>
<decimal value="0" />
</trueValue>
<falseValue>
<decimal value="1" />
</falseValue>
</boolean>
<boolean id="PopupMenu_Object" valueName="{7823A620-9DD9-11CF-A662-00AA00C066D2}">
<trueValue>
<decimal value="0" />
</trueValue>
<falseValue>
<decimal value="1" />
</falseValue>
</boolean>
<boolean id="Ikonic_Control" valueName="{F5131C24-E56D-11CF-B78A-444553540000}">
<trueValue>
<decimal value="0" />
</trueValue>
<falseValue>
<decimal value="1" />
</falseValue>
</boolean>
</elements>
</policy>
<policy name="Microsoft_Agent" class="User" displayName="$(string.Microsoft_Agent)" explainText="$(string.IE_Explain_Microsoft_Agent)" presentation="$(presentation.Microsoft_Agent)" key="Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls">
<parentCategory ref="AdminApproved" />
<supportedOn ref="SUPPORTED_IE5" />
<elements>
<boolean id="Microsoft_Agent_Control" valueName="{D45FD31B-5C6E-11D1-9EC1-00C04FD7081F}">
<trueValue>
<decimal value="0" />
</trueValue>
<falseValue>
<decimal value="1" />
</falseValue>
</boolean>
</elements>
</policy>
my expected result :
name="Menu_Controls" key="Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls"
name="Microsoft_Agent" key="Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls"
thanks in advance for your help.
toshi
two cmds could do it:
v/<policy /d
then
%s/.* \(name="[^"]*"\).*\(key="[^"]*"\).*/\1 \2/g
My ExtractMatches plugin provides a :YankMatches command, with which you can extract the matches and put them into a scratch buffer. As a one-liner:
:execute 'YankMatches \<\%(name\|key\)="[^"]*"' | new | put!
Result:
name="Menu_Controls"
key="Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls"
name="Microsoft_Agent"
key="Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\AllowedControls"
If you find :vimgrep and the quickfix list really helpful, you can use the editqf.vim plugin to make the quickfix list of your grep results editable, and then use e.g. a variation of the :%s command given in #Kent's answer to strip off the extraneous stuff.

Ribbon button should be hidden based on lead status - CRM 2011

I have custom button in lead ribbon. The custom button should be hidden when lead is qualified. How can I do that? Can any one please explain. I appreciate.
You can actually accomplish this entirely with built-in DisplayRule functionality. When a Lead is qualified, the StatusCode property is set to "Qualified", which translates into an OptionSet value of "3". You can check for the value of this property in a ValueRule and display/hide the control appropriately. I can think of two ways to achieve this:
Erik Pool's Visual Ribbon Editor
RibbonXml
<RibbonDiffXml>
<CustomActions>
<CustomAction Id="CompanyName.Form.lead.MainTab.Actions.Sample.CustomAction" Location="Mscrm.Form.lead.MainTab.Actions.Controls._children" Sequence="41">
<CommandUIDefinition>
<Button Id="CompanyName.Form.lead.MainTab.Actions.Sample" Command="CompanyName.Form.lead.MainTab.Actions.Sample.Command" Sequence="29" ToolTipTitle="$LocLabels:CompanyName.Form.lead.MainTab.Actions.Sample.LabelText" LabelText="$LocLabels:CompanyName.Form.lead.MainTab.Actions.Sample.LabelText" ToolTipDescription="$LocLabels:CompanyName.Form.lead.MainTab.Actions.Sample.Description" TemplateAlias="isv" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
</Templates>
<CommandDefinitions>
<CommandDefinition Id="CompanyName.Form.lead.MainTab.Actions.Sample.Command">
<EnableRules />
<DisplayRules>
<DisplayRule Id="CompanyName.Form.lead.MainTab.Actions.Sample.Command.DisplayRule.ValueRule" />
</DisplayRules>
<Actions>
<Url Address="http://www.bing.com" />
</Actions>
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules>
<DisplayRule Id="CompanyName.Form.lead.MainTab.Actions.Sample.Command.DisplayRule.ValueRule">
<ValueRule Field="statuscode" Value="3" />
</DisplayRule>
</DisplayRules>
<EnableRules />
</RuleDefinitions>
<LocLabels>
<LocLabel Id="CompanyName.Form.lead.MainTab.Actions.Sample.LabelText">
<Titles>
<Title languagecode="1033" description="Sample" />
</Titles>
</LocLabel>
<LocLabel Id="CompanyName.Form.lead.MainTab.Actions.Sample.Description">
<Titles>
<Title languagecode="1033" description="Sample Description" />
</Titles>
</LocLabel>
</LocLabels>
</RibbonDiffXml>

Resources