Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 213 Vote(s) - 3.73 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Web.Config transforms outside of Microsoft MSBuild?

#1
Is it possible to use Microsoft's XML document transform, for preparing web.configs, outside of MSBuild? I would like to use PowerShell to do these transform without having to run this through the MSBuild engine. If Microsoft had used standard XSLT it would be easy to do in PowerShell. From what I can tell I have to use their C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll which requires a build engine.
Thanks
Reply

#2
Take a looked at using MSDeploy since it has PowerShell scripting APIs that allow you to transform and deploy your package.

You can also look at [XML-Document-Transform][1] which if you wanted to you can write your own code to perform the Transform.

Here is a codeplex project that did something similar.[XDT Transformation Tool][2]


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#3
Based on Michel's answer I wrote a C# function that will accomplish the same.

Of course you could invoke the resultant DLL with PowerShell, but I was actually looking for a fully programatic version, so here it is, in case anybody else is looking for similar solution:

using Microsoft.Web.XmlTransform;

...

public static void TransformConfig(string configFileName, string transformFileName)
{
var document = new XmlTransformableDocument();
document.PreserveWhitespace = true;
document.Load(configFileName);

var transformation = new XmlTransformation(transformFileName);
if (!transformation.Apply(document))
{
throw new Exception("Transformation Failed");
}
document.Save(configFileName);
}

You will just need to include reference to following:

> C:\Program Files
> (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.XmlTransform.dll
Reply

#4
Microsoft has posted XDT to codeplex

[To see links please register here]

and as a NuGet package

[To see links please register here]

. I have also created a NuGet pig with an MSBuild task, TransformXml, and an .exe to invoke them

[To see links please register here]

.

For PowerShell I've created a self-bootstrapping script which you can use .

More about self bootstrapping scripts at

[To see links please register here]

.

Reply

#5
I updated the script a bit to make it work with the latest version of powershell and make it a bit easier.

function XmlDocTransform($xml, $xdt)
{
$scriptpath = $PSScriptRoot + "\"
$xmlpath = $scriptpath + $xml
$xdtpath = $scriptpath + $xdt

if (!($xmlpath) -or !(Test-Path -path ($xmlpath) -PathType Leaf)) {
throw "Base file not found. $xmlpath";
}

if (!($xdtpath) -or !(Test-Path -path ($xdtpath) -PathType Leaf)) {
throw "Transform file not found. $xdtpath";
}

Add-Type -LiteralPath "$PSScriptRoot\Microsoft.Web.XmlTransform.dll"

$xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$xmldoc.PreserveWhitespace = $true
$xmldoc.Load($xmlpath);

$transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdtpath);
if ($transf.Apply($xmldoc) -eq $false)
{
throw "Transformation failed."
}
$xmldoc.Save($xmlpath);

Write-Host "Transformation succeeded" -ForegroundColor Green
}

And to invoke the function use



XmlDocTransform "App.config" "App.acc.config"
Reply

#6
I created a small function to handle Microsoft's XML Document Transform in PowerShell.

I copied the Microsoft.Web.XmlTransform.dll file from Visual Studio build folder to my script's path, but you can reference it from the source folder if you'd like.

function XmlDocTransform($xml, $xdt)
{
if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
throw "File not found. $xml";
}
if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
throw "File not found. $xdt";
}

$scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
Add-Type -LiteralPath "$scriptPath\Microsoft.Web.XmlTransform.dll"

$xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$xmldoc.PreserveWhitespace = $true
$xmldoc.Load($xml);

$transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
if ($transf.Apply($xmldoc) -eq $false)
{
throw "Transformation failed."
}
$xmldoc.Save($xml);
}

To transform web.config using web.release.config:

XmlDocTransform -xml "Web.config" -xdt "Web.Release.config"

Alternatively, you can use Sayed's self-bootstraping Xml Transform script, which will take care of getting the Microsoft.Xml.Xdt.dll for you:

Reply

#7
So extended slightly to work recursively

function XmlDocTransform($xml, $xdt)
{
if (!$xml -or !(Test-Path -path $xml -PathType Leaf)) {
throw "File not found. $xml";
}
if (!$xdt -or !(Test-Path -path $xdt -PathType Leaf)) {
throw "File not found. $xdt";
}
$scriptPath = (Get-Variable MyInvocation -Scope 1).Value.InvocationName | split-path -parent
Add-Type -LiteralPath "$scriptPath\Microsoft.Web.XmlTransform.dll"
$xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$xmldoc.PreserveWhitespace = $true
$xmldoc.Load($xml);
$transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdt);
if ($transf.Apply($xmldoc) -eq $false)
{
throw "Transformation failed."
}
$xmldoc.Save($xml);
}
function DoConfigTransform($webFolder, $environment)
{
$allConfigFiles = Get-ChildItem $webFolder -File -Filter *.config -Recurse
$transformFiles = $allConfigFiles | Where-Object {$_.Name -like ("*." + $environment + ".config")} | %{$_.fullname}
ForEach($item in $transformFiles)
{
$origFile = $item -replace("$environment.",'')
XmlDocTransform -xml $origFile -xdt $origFile$item
#Write-Output ("orig = " + $origFile + ", transform = " + $item)
}
cd C:\WebApplications\xxx\xxx\xxx\
.\PostDeploy.ps1
}
DoConfigTransform -webFolder "C:\WebApplications\xxx\xxx\xxx" -environment "xx-xxx-xx"

So the DoConfigTransform logic goes:

- Find all config files recursively
- Find all transform templates for the environment we are in #passed in as a parameter
- For each transform file, find the corresponding config
- Then do transform
- Code runs a postdeploy script to remove all unwanted transform files.
Reply

#8
The logic of the transformation is contained inside of the TransformXml task itself. If you want to call it from code you would have to use the MSBuild API with a mock engine and execute it. I have some code for this if you want.

In your case since you mentioned PowerShell the best thing for you to do is to just create a wrapper MSBuild file to invoke the TransformXml task. I say this because PowerShell is configured to run under .NET 2.0, but the TransformXml task requires .NET 4.0. In order to call it from a dummy MSBuild file you can check my blog at

[To see links please register here]

, but I've also pasted a sample from that link below.

<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>

<Target Name="Demo">
<TransformXml Source="app.config"
Transform="Transform.xml"
Destination="app.prod.config"/>
</Target>
</Project>

For `mono`, this should work (tested on mono 6.4, macos, 2019) :

<Project DefaultTargets="TransformConfig" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="TransformXml"
AssemblyFile="$(MSBuildSDKsPath)/Microsoft.NET.Sdk.Publish/tools/net46/Microsoft.NET.Sdk.Publish.Tasks.dll"/>
<PropertyGroup>
<TransformSource>Web.config</TransformSource>
<Transformer>Web.Live.config</Transformer>
<Destination>Output.Web.config</Destination>
</PropertyGroup>
<Target Name="TransformConfig">
<Message Text="From TransformSource : $(TransformSource)" />
<Message Text="Using Transform : $(Transformer)" />
<Message Text="Output : $(Destination)" />
<Message Text="MSBuildSDKsPath=$(MSBuildSDKsPath)" Condition="'$(MSBuildSDKsPath)' != ''" />
<TransformXml Source="$(TransformSource)" Transform="$(Transformer)" Destination="$(Destination)"/>
</Target>
</Project>

which you can run with just `msbuild` or supply parameters with

msbuild /p:TransformSource=... /p:Transformer=...


Reply

#9
I came to this post well after it original posting but it helped resolve my issue so I thought I'd put my solution (based on the solution above) here for anyone having the same problem with a current visual studio / msbuild install.

Currently in VS build time transforms are done using the SlowCheetah nuget pkg. If you can rely on this package in your project you can use the script I have placed below and it will automatically find the required assembly based on the installed cheetah version and perform your transform as needed.

Hope this helps someone.


```PowerShell
param(
[ValidateScript({$(Test-Path $_) -eq $true})]
[string] $NuGetRootPath,

[ValidateScript({$(Test-Path $_) -eq $true})]
[string] $BaseFile,

[ValidateScript({$(Test-Path $_) -eq $true})]
[string] $TransformFile,

[string] $TargetPath
)

"[INFO] Creating Custom XML Transform..." | Out-Default
"[INFO] ==> Source: $BaseFile" | Out-Default
"[INFO] ==> Transform: $TransformFile" | Out-Default
"[INFO] ==> Target: $TargetPath" | Out-Default

$cheetahDir = Join-Path $NuGetRootPath *SlowCheetah* | Resolve-Path | Select-Object -Last 1 -ExpandProperty Path
$xformDll = Join-Path $cheetahDir "tools\Microsoft.Web.XmlTransform.dll" | Resolve-Path | Select-Object -ExpandProperty Path
Add-Type -LiteralPath $xformDll

$xmldoc = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$xmldoc.PreserveWhitespace = $true
$xmldoc.Load($BaseFile);

"[INFO] Running Transform..." | Out-Default
$transf = New-Object Microsoft.Web.XmlTransform.XmlTransformation($TransformFile);
if ($transf.Apply($xmldoc) -eq $false) {
throw "[ERROR] Transformation failed."
}

$xmldoc.Save($TargetPath);
"[INFO] Transformation Complete..." | Out-Default
```

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through