I've a problem with forceing NAT mode on network cards in all VirtualBox machines. The only solution I have found is to replace the code in the configuration file located in the C:\Users\USER\VirtualBoxVMs\VirtualMachineName\VirtualMachineName.vbox.
Unfortunately, I cannot simply replace these files because each user has different settings (such as the name of the VM)
I have to replace the text in the
<Adapter>...<Adapter> tag. Doing it on one computer for one user is not a problem. I can't deal with the fact that I have to do it with a script on multiple computers for all users. So far, I've managed to do something like this, and I don't know what to do next.
$InputFiles = Get-Item "C:\Users\*\VirtualBox VMs\*\*.vbox"
$OldString = '<Adapter ...various computer-dependent variables...>
...
...
</Adapter>'
$NewString = '<Adapter ...various computer-dependent variables...>
<NAT/>
</Adapter>'
$InputFiles | ForEach {
(Get-Content -Path $_.FullName).Replace($OldString,$NewString) | Set-Content -Path $_.FullName
}
Another complication is that when saving changes, everything is saved in one file for all users, i.e. all settings from all machines on a given computer as one file.
Unfortunately, VB does not store such values in the register, which makes it very difficult. Maybe there is another, easy way?
EDIT: Sample VBox config file
<?xml version="1.0"?>
<!--
** DO NOT EDIT THIS FILE.
** If you make changes to this file while any VirtualBox related application
** is running, your changes will be overwritten later, without taking effect.
** Use VBoxManage or the VirtualBox Manager GUI to make changes.
-->
<VirtualBox xmlns="http://www.virtualbox.org/" version="1.15-windows">
<Machine uuid="{1d96510c-97ce-4671-a1df-3f08c7d2b2c7}" name="TEST" OSType="Windows7_64" snapshotFolder="Snapshots" lastStateChange="2020-05-04T09:56:34Z">
<MediaRegistry>
<HardDisks>
<HardDisk uuid="{eab23143-54ec-4f7d-822d-a56bf90a58bb}" location="TEST.vdi" format="VDI" type="Normal"/>
</HardDisks>
</MediaRegistry>
<ExtraData>
<ExtraDataItem name="GUI/FirstRun" value="yes"/>
</ExtraData>
<Hardware>
<CPU>
<PAE enabled="false"/>
<LongMode enabled="true"/>
<HardwareVirtExLargePages enabled="true"/>
</CPU>
<Memory RAMSize="2048"/>
<HID Pointing="USBTablet"/>
<Paravirt provider="Default"/>
<Display VRAMSize="18"/>
<VideoCapture fps="25" options="ac_enabled=false"/>
<RemoteDisplay enabled="false"/>
<BIOS>
<IOAPIC enabled="true"/>
</BIOS>
<USB>
<Controllers>
<Controller name="OHCI" type="OHCI"/>
<Controller name="EHCI" type="EHCI"/>
</Controllers>
</USB>
<Network>
<Adapter slot="0" enabled="true" MACAddress="MACAddress" cable="true" type="82540EM">
<NAT/>
</Adapter>
</Network>
<AudioAdapter controller="HDA" driver="DirectSound" enabled="true" enabledIn="false"/>
</Hardware>
<StorageControllers>
<StorageController name="SATA" type="AHCI" PortCount="2" useHostIOCache="false" Bootable="true" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
<AttachedDevice type="HardDisk" hotpluggable="false" port="0" device="0">
<Image uuid="{eab23143-54ec-4f7d-822d-a56bf90a58bb}"/>
</AttachedDevice>
<AttachedDevice passthrough="false" type="DVD" hotpluggable="false" port="1" device="0"/>
</StorageController>
</StorageControllers>
</Machine>
</VirtualBox>
Related
I have a build pipeline in Azure DevOps, I need to update the build number in my apconfig exe file that will be $(Build.BuildNumber).
I just tried this way:
Adding a variable name = BuildNumber value = $(Build.BuildNumber).
And in my apconfig.exe file have a key same like <add key="BuildNumber" value="1812201901" />.
Why I have tried like this way: thinking like it will update in the config file if variable name match with the key.
But it is not working. can anyone please help? I have just started in CI/CD.
Update Build number in App config xml file on build pipeline
Just like the Shayki said, using the Replace Tokens extension should be the directly way to resolve this issue.
But since you need to request to get this extension, as workaround, you could also use power shell scripts to resolve this issue, you can check below my test powershell scripts:
$currentDirectory = [IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path)
$appConfigFile = [IO.Path]::Combine($currentDirectory, 'App.config')
$appConfig = New-Object XML
$appConfig.Load($appConfigFile)
foreach($BuildNumber in $appConfig.configuration.add)
{
'name: ' + $BuildNumber.name
'BuildNumber: ' + $BuildNumber.value
$BuildNumber.value = '123456789'
}
$appConfig.Save($appConfigFile)
As result, the app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<add key="BuildNumber" value="123456789" />
</configuration>
Note: Set the powershell scripts at the same folder of the app.config file.
Hope this helps.
You can use the Replace Tokens extension and in the apconfig.exe file put this:
<add key="BuildNumber" value="__BuildNumber__" />
Configure the task to search variables with __ prefix and suffix:
Now the value will be replaced with the value of the BuildNumber variable you configured (equal to Build.BuildNumber).
I know that when creating a release pipeline in Azure DevOps you can have the web.config of an app updated with variables from the pipeline and that works great for all the appSettings values.
But, during the release pipeline I'd like to update a different section of the web.config, specifically the sessionState provider node. I've tried a few plugins for the release pipeline like Config Transform by Magic Chunks but the problem is it needs you to specify the path of the configuration file to edit but by the time it gets to the release pipeline the source files are in a zip archive. Somehow the normal transformations of the appSettings are able to work off the unzipped version but I can't get other transformations to happen after the file is unzipped.
I know you can make changes in the build pipeline but there are reasons we want to do it in the release pipeline.
Anyone know a way to make changes to the web.config outside of the appSettings grouping in a release pipeline for an Azure App Service?
You can use PowerShell to do the transformation within the zip file.
For example, I have this node in the web.config:
<configuration>
<sessionstate
mode="__mode__"
cookieless="false"
timeout="20"
sqlconnectionstring="data source=127.0.0.1;user id=<user id>;password=<password>"
server="127.0.0.1"
port="42424"
/>
</configuration>
I use this script:
# cd to the agent artifcats direcory (where the zip file exist)
cd $env:Agent_ReleaseDirectory
$fileToEdit = "web.config"
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zipfileName = dir -filter '*.zip'
$zip = [System.IO.Compression.ZipFile]::Open($zipfileName.FullName,"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 '__mode__',"stateserver"
#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()
Before:
After (inside the zip file, without unzip and re-zip):
I was looking to do something similar, but found that there is a built-in task called File Transform [https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/file-transform?view=azure-devops] by Microsoft. With it, all you have to do is define a variable with the key in web.config if it is a simple substitute. If you need more involved transformation you can specify that too.
Since I had edge case, where I got 405 status on PUT and DELETE as seen here:
WebAPI Delete not working - 405 Method Not Allowed
which required me to change web.config file that is created only when project is released. So I needed to insert couple of lines of code in web.config like:
<modules>
<remove name="WebDAVModule" />
</modules>
and few more.
My answer is based on #Shayki Abramczyk one, I think it offers another, updated, take on this issue.
As his answer did not work fully for me, and for someone who is not professional in field of DevOps, rather programmer that wanted to automate the CI-CD stuff.
Issue I think is present nowadays is that line:
cd $env:Agent_ReleaseDirectory
is not navigating to proper folder. You still need to navigate to the folder and drop where your zip file is like so: cd _Your.Project-CI\drop
So start by adding another PowerShell component in your release pipeline like so:
And add following code to it:
# cd to the agent artifacts directory (where the zip file exist)
cd $env:Agent_ReleaseDirectory
cd _Your.Project-CI\drop
$fileToEdit = "web.config"
[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zipfileName = dir -filter '*.zip'
$zip = [System.IO.Compression.ZipFile]::Open($zipfileName.FullName,"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()
$contentToAdd1 = #'
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
'#
#$text[3] = $text[3] -replace '<system.webServer>',$contentToAdd1
$text = $text -replace '<system.webServer>',$contentToAdd1
$contentToAdd2 = #'
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE,DEBUG" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
'#
# $text[4] = $text[4] -replace '<handlers>',$contentToAdd2
$text = $text -replace '<handlers>',$contentToAdd2
#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()
Only thing that is left to do is to replace: cd _Your.Project-CI\drop with your project name e.g. cd _Weather.Front-CI\drop.
I am using the powershell GroupPolicy module to create and link new GPOs. I have a large number of GPOs to create, and thus I wish to automate the process without having to interact with the Group Policy Editor.
I noticed while creating GPOs through the editor that each policy object would be contained in either one or several XML files or .INI files.
Having noted above, I started creating GPOs with the New-GPO command, passing the -Name and -Domain flags. After the GPO has been successfully created, I would (via my script) generate an XML file containing all of the information that the policy would consume. Shown below is an extract of the XML file that I would create to set up a mapped drives policy.
When inspecting the policy in the editor, everything looks fine. The correct drives are showing up and all of the settings appear to be correct. However, the policy is never applied. If I create an identical policy manually via the Group Policy Editor, all of the policies start working, including the ones that I created with powershell.
The error therefore seems to be that the domain controller is never made aware of the changes, but they get applied when a manual change is made.
I have tried running gpupdate /force, which does not seem to update or propagate the changes
New-Item \\$($MappedDrivesGPO.DomainName)\SYSVOL\$($MappedDrivesGPO.DomainName)\Policies\$("{"+$MappedDrivesGPO.Id+"}")\User\Preferences\Drives\Drives.xml -ItemType File -Force
Set-Content \\$($MappedDrivesGPO.DomainName)\SYSVOL\$($MappedDrivesGPO.DomainName)\Policies\$("{"+$MappedDrivesGPO.Id+"}")\User\Preferences\Drives\Drives.xml $xml
<?xml version="1.0" encoding="utf-8"?>
<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}">
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="P:" status="P:" image="2" changed="2019-04-26 10:41:54" uid="{$guid1}" bypassErrors="1">
<Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\fs1\Projects" label="Projects" persistent="0" useLetter="1" letter="P"/>
<Filters>
<FilterGroup bool="AND" not="0" name="$($domainName)\Drive P Access" sid="$($filterGroupSidDriveP)" userContext="1" primaryGroup="0" localGroup="0"/>
</Filters>
</Drive>
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="S:" status="S:" image="2" changed="2019-04-26 10:39:21" uid="{$guid2}" bypassErrors="1">
<Properties action="U" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="" path="\\as1\Software" label="Software" persistent="0" useLetter="1" letter="S"/>
<Filters>
<FilterGroup bool="AND" not="0" name="$($domainName)\Drive S Access" sid="$($filterGroupSidDriveS)" userContext="1" primaryGroup="0" localGroup="0"/>
</Filters>
</Drive>
</Drives>
I expected the policy to start working as intended after the XML file had been created
The actual result is that the policy appears to be well formed, but never applied
I managed to resolve this on my own, posting here in case someone else runs into the same issue. If you're creating GPOs programmatically and not via the editor, you will have to extend your script/program to add CSE (in this case for drive mapping) and SnapIn GUID to gPCUserExtensionNames.
[{00000000-0000-0000-0000-000000000000}{2EA1A81B-48E5-45E9-8BB7-A6E3AC170006}][{5794DAFD-BE60-433F-88A2-1A31939AC01F}{2EA1A81B-48E5-45E9-8BB7-A6E3AC170006}]
The 0000.. is the Core GPO Engine, 23EA.. is the Preference Tool CSE GUID Drives, 5794.. is Preference CSE GUID Drives.
If you create the policy manually with the desired changes, you can then open dsa.msc, enable advanced features and then view the policy object properties. Under gPCUserExtensionNames you will be able to see the arrays containing the GUIDs that you need to incorporate in your software.
I have a vmConfig file. I want to change subnet and IP Address as I want to create a new VM out of config file in new subnet, rest all configurations no need to be changed. I can manually edit xml file content but I want to do it through powershell so that I can have an automated process for everything.
Here is the sample vmConfig xml-
<?xml version="1.0" encoding="utf-8"?>
<PersistentVM xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ConfigurationSets>
<ConfigurationSet xsi:type="NetworkConfigurationSet">
<ConfigurationSetType>NetworkConfiguration</ConfigurationSetType>
<InputEndpoints>
<InputEndpoint>
<LocalPort>5986</LocalPort>
<Name>PowerShell</Name>
<Port>64929</Port>
<Protocol>tcp</Protocol>
<Vip>191.237.20.225</Vip>
<EnableDirectServerReturn>false</EnableDirectServerReturn>
<IdleTimeoutInMinutes xsi:nil="true" />
</InputEndpoint>
</InputEndpoints>
<SubnetNames>
<string>mysubnet</string>
</SubnetNames>
<StaticVirtualNetworkIPAddress>12.13.14.15</StaticVirtualNetworkIPAddress>
<PublicIPs />
<NetworkInterfaces />
I am interested changing only IP Address and Subnet.
This is basically xml parsing using powershell. I hope this should work for you-
$path = 'C:\myFolder\XmlVM.xml'
[xml]$myXML = Get-Content $path
$myXML.PersistentVM.ConfigurationSets.ConfigurationSet.SubnetNames.string="MYNEWSUBNET"
$myXML.PersistentVM.ConfigurationSets.ConfigurationSet.StaticVirtualNetworkIPAddress="10.11.14.115"
$myXML.Save($path)
I've been working on a NuGet package for my company and one of the requirements is being able to update some of our config files.
I know it's possible to add to a config file, but is it possible to edit one?
Example:
<add name="conn" connectionString="Data Source=.\;Initial Catalog=DB;Integrated Security=True" />
changes to below
<add name="conn" connectionString="Data Source=.\;Initial Catalog=DB;User ID=ex;Password=example" />
NuGet transforms can't edit existing values. But NuGet lets you run Powershell scripts on package install, so you can edit the config file that way.
Create an Install.ps1 file and use this code:
# Install.ps1
param($installPath, $toolsPath, $package, $project)
$xml = New-Object xml
# find the Web.config file
$config = $project.ProjectItems | where {$_.Name -eq "Web.config"}
# find its path on the file system
$localPath = $config.Properties | where {$_.Name -eq "LocalPath"}
# load Web.config as XML
$xml.Load($localPath.Value)
# select the node
$node = $xml.SelectSingleNode("configuration/connectionStrings/add[#name='gveconn']")
# change the connectionString value
$node.SetAttribute("connectionString", "Data Source=.\;Initial Catalog=GVE;User ID=ex;Password=example")
# save the Web.config file
$xml.Save($localPath.Value)
As of NuGet 2.6 and above, you can actually transform Web.config files using the XDT syntax that is used for Web.config transforms in Visual studio.
See http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations:
Support for XML-Document-Transform (XDT)
Starting with NuGet 2.6, XDT is supported to transform XML files inside a project. The XDT syntax can be utilized in the .install.xdt and .uninstall.xdt file(s) under the package's Content folder, which will be applied during package installation and uninstallation time, respectively.
For example, to add MyNuModule to web.config file like what's illustrated above, the following section can be used in the web.config.install.xdt file:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>
<modules>
<add name="MyNuModule" type="Sample.MyNuModule" xdt:Transform="Insert" />
</modules>
</system.webServer>
</configuration>
On the other hand, to remove only the MyNuModule element during package uninstall, the following section can be used in the web.config.uninstall.xdt file:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>
<modules>
<add name="MyNuModule" xdt:Transform="Remove" xdt:Locator="Match(name)" />
</modules>
</system.webServer>
</configuration>
EDIT: The answer is now YES as of NUGET 2.6 and above.
The answer is NO. From the nuget site I found the following answer:
"When NuGet merges a transform file into a project's configuration file, it only adds elements or adds attributes to existing elements in the configuration file; it does not change existing elements or attributes in any other way."
http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations
Yes, it's possible, but you have to include install.ps1 file into tools folder. And then when you will get your package from nuget server, visual studio run Powershell scripts.
I use this script
# fileName can be App.Config Or Web.Config or something else
$fileName = "App.Config"
$file=$project.ProjectItems.Item($fileName)
if($file.Properties){
# Get localpath
$localPath = $file.Properties.Item("LocalPath")
if($localPath){
$localPath = $localPath.Value
}
}
if ($localPath -eq $null) {
Exit
}
#Load our config file as XML file
[xml]$file = Get-Content $localPath
if($file){
# Create node
$childNode = $file.CreateElement("add")
$childNode.SetAttribute("connectionString", "DataSource=.\;InitialCatalog=GVE;User ID=ex;Password=example")
#Get parent node
$node = $file.SelectSingleNode("configuration/connectionStrings")
#Insert our node into parent
$node.AppendChild($childNode)
$file.Save($localPath)
}