MSDeploy v3 - xpath-based default parameter values doesn't appear to workRSS

11 replies

Last post Jul 10, 2013 04:05 PM by elliott_h

  • MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Nov 04, 2012 05:32 PM|richard.szalay|LINK

    According to the documentation page Parameterization improvements in Web Deploy V3, XmlFile parameter values can be given a defaultValue that infers the value from an existing xml file. The following example is given:

    <parameter name="Replacement Param" defaultValue="\web.config:://connectionStrings" >”<parameterEntry kind="XMLFILE" scope="web\.config$" match="//connectionStrings" /></parameter>

    I can't get this feature to work at all. Did the implementation make it into v3 RTW or was it culled (like app_offline templates)?

    Here's my first example (of two), which declares a parameter on an XML element and gives it a default value of an element loaded from a different file (to make sure the feature works):

    @echo off

    REM ******** this stuff is only to read the path to the latest WebDeploy on your machine ***********
    for /F "usebackq tokens=1,2,*" %%h  in (`reg query "HKLM\SOFTWARE\Microsoft\IIS Extensions\MSDeploy" /s  ^| findstr -i "InstallPath"`) do (
    if /I "%%h" == "InstallPath" (
    if /I "%%i" == "REG_SZ" (
    if not "%%j" == "" (
    if "%%~dpj" == "%%j" (
    set MSDEPLOY="%%j\msdeploy"
    )))))

    mkdir source & mkdir dest
    echo ^<configuration^> ^
        ^<appSettings^> ^
            ^<add key="test" value="original" /^> ^
        ^</appSettings^> ^
     ^</configuration^> > source\web.config

    echo ^<configuration^> ^
        ^<appSettings^> ^
            ^<add key="test" value="default" /^> ^
        ^</appSettings^> ^
     ^</configuration^> > source\default.config

    @echo on
     
    @echo. & @echo Packaging
    %MSDEPLOY% -verb:sync -source:contentPath=%cd%\source -dest:package=%cd%\package.zip ^
     -declareParam:name="test",kind=XmlFile,scope=Web\.config,match=//add[@key='test'],defaultValue=\default.config:://add[@key='test']

    @echo. & @echo Deploying with default value
    %MSDEPLOY% -verb:sync -source:package=%cd%\package.zip -dest:contentPath=%cd%\dest
    @find "test" dest\web.config
    @echo. & @echo "value" attribute expected to be "default"

    @PAUSE

    @echo. & echo Deploying with updated value
    %MSDEPLOY% -verb:sync -source:package=%cd%\package.zip -dest:contentPath=%cd%\dest -setParam:name="test",value="^<add key=^"test^" value=^"updated^" /^>"
    @find "test" dest\web.config
    @echo. & @echo "value" attribute expected to be "updated"

    @PAUSE

    The output is summarised as follows:

    Dumping parameters
    <output>
      <parameters>
        <parameter name="test" defaultValue="\default.config:://add[@key='test']">
          <parameterEntry kind="XmlFile" scope="Web\.config" match="//add[@key='test']" />
        </parameter>
      </parameters>
    </output>

    Deploying with default value
    <configuration>     <appSettings>         <add key="test" value="original" />     </appSettings>  </configuration>
    "value" attribute expected to be "default"

    Deploying with updated value
    <configuration>     <appSettings>         <add key="test" value="original" />     </appSettings>  </configuration>
    "value" attribute expected to be "updated"

    Which appears to be ignoring the parameter entirely.

    My next example does the same thing, but defines the parameter (and default value) on an attribute

    @echo off

    REM ******** this stuff is only to read the path to the latest WebDeploy on your machine ***********
    for /F "usebackq tokens=1,2,*" %%h  in (`reg query "HKLM\SOFTWARE\Microsoft\IIS Extensions\MSDeploy" /s  ^| findstr -i "InstallPath"`) do (
    if /I "%%h" == "InstallPath" (
    if /I "%%i" == "REG_SZ" (
    if not "%%j" == "" (
    if "%%~dpj" == "%%j" (
    set MSDEPLOY="%%j\msdeploy"
    )))))

    mkdir source & mkdir dest
    echo ^<configuration^> ^
        ^<appSettings^> ^
            ^<add key="test" value="original" /^> ^
        ^</appSettings^> ^
     ^</configuration^> > source\web.config

    echo ^<configuration^> ^
        ^<appSettings^> ^
            ^<add key="test" value="default" /^> ^
        ^</appSettings^> ^
     ^</configuration^> > source\default.config

    @echo on
     
    @echo. & @echo Packaging
    %MSDEPLOY% -verb:sync -source:contentPath=%cd%\source -dest:package=%cd%\package.zip ^
     -declareParam:name="test",kind=XmlFile,scope=web\.config,match=//add[@key='test']/@value,defaultValue=\default.config:://add[@key='test']/@value

    @echo. & @echo Dumping parameters
    %MSDEPLOY% -verb:getParameters -source:package=%cd%\package.zip

    @echo. & @echo Deploying with default value
    %MSDEPLOY% -verb:sync -source:package=%cd%\package.zip -dest:contentPath=%cd%\dest
    @find "test" dest\web.config
    @echo. & @echo "value" attribute expected to be "default"

    @PAUSE

    @echo. & echo Deploying with updated value
    %MSDEPLOY% -verb:sync -source:package=%cd%\package.zip -dest:contentPath=%cd%\dest -setParam:name="test",value="updated"
    @find "test" dest\web.config
    @echo. & @echo "value" attribute expected to be "updated"

    @PAUSE

    The output is summarised as follows:

    Dumping parameters
    <output>
      <parameters>
        <parameter name="test" defaultValue="\default.config:://add[@key='test']/@value">
          <parameterEntry kind="XmlFile" scope="web\.config" match="//add[@key='test']/@value" />
        </parameter>
      </parameters>
    </output>

    Deploying with default value
    <configuration>     <appSettings>         <add key="test" value="\default.config:://add[@key='test']/@value" />     </appSettings>  </configuration>
    "value" attribute expected to be "default"

    Deploying with updated value
    <configuration>     <appSettings>         <add key="test" value="updated" />     </appSettings>  </configuration>
    "value" attribute expected to be "updated"

    Which only works correctly when an explicit value is set.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Nov 26, 2012 04:47 AM|richard.szalay|LINK

    Any chance I could get some acknowledgement on my original post? Don't get me wrong, I do enjoy writing detailed bug descriptions and repro scripts, as it gives me something to pass the long hours. Still, it'd be nice to get some feedback from the team.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 12, 2012 11:16 AM|TuesdaysGreen|LINK

    Hi Richard.  There was a lot of information in your post, but what I believe you're trying to do in the first part was to add a key to your configuration file.  If so, then you want to craft your parameters file like below:

    <parameters>
         <parameter name="test" defaultValue="&lt;add key='test' /&gt;">
           <parameterEntry kind="XmlFile" scope="Web\.config" match="//appsettings" />
         </parameter>
       </parameters>

    If you want to add a child element, then you want to match on the parent element and set the value/defaultvalue to what's being insertted.  When calling "-setParam" on this parameter, you should be able to use it the same way you're already doing (by not escaping the '<' and '>' signs.)

    Also if you're not sure whether Web Deploy is matching a parameter or not, add the "-verbose" tag and it will tell you.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 12, 2012 11:41 PM|richard.szalay|LINK

    Hi Tuesdays,

    Actually, I'm trying to load the default value for a parameter from an external file as described at this page: http://www.iis.net/learn/publish/using-web-deploy/parameterization-improvements-in-web-deploy-v3

    Below are some examples which demonstrate how to get the values from other placesGet values from remote server:

    <parameter name="Replacement Param" defaultValue="\\myshare\share\web.config:://connectionStrings" >”<parameterEntry kind="XMLFILE" scope="web\.config$" match="//connectionStrings" /></parameter>
    Get values from a file in the package that is being synced:

    <parameter name="Replacement Param" defaultValue="\web.config:://connectionStrings" >”<parameterEntry kind="XMLFILE" scope="web\.config$" match="//connectionStrings" /></parameter>

    Having said that, your question actually answers this other poster's question, so I'd recommend letting him know.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 14, 2012 11:12 AM|TuesdaysGreen|LINK

    Hi Richard.  Could you add the "-verbose" argument and post the output of that please?  Also if you could send a snippet of your source config file that you're trying to read from, that would also be helpful.

    Thanks,
    Elliott 

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 15, 2012 06:20 PM|richard.szalay|LINK

    Hi Elliot,

    The web.configs were actually created by the repro script (which is completely stand alone in reproducing the bug) in my original post, but I'll include them here:

    <!-- web.config -->
    <configuration>
      <appSettings>
        <add key="test" value="original" />
      </appSettings>
    </configuration>
    
    <!-- default.config -->
    <configuration>
      <appSettings>
        <add key="test" value="default" />
      </appSettings>
    </configuration>

    I've added the verbose call and here is the relevant output from packaging:

    Info: Adding declared parameter 'test'.

    Deploying with the default value (with personal paths replaced with _REPRO_DIR_):

    Verbose: Parameter entry 'test/1' is applicable to '_REPRO_DIR_\source\web.config' because of its scope.
    Verbose: Parameter entry 'test/1' could not be applied to '_REPRO_DIR_\source\web.config'. Deployment will continue with the original data. Details:
    Could not add value '\default.config:://add[@key='test']' within element 'add' because value is not valid XML.

    The custom value is not relevant as it does not utilise the feature in question (and my original script had a typo causing it to fail).

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 17, 2012 12:05 PM|TuesdaysGreen|LINK

    Edit - It seems like a lot of people are confused by this feature, so I added a blog entry which goes through some of these scenario's we've been discussing.  Web Deploy XML Parameterization  

     

    Hi Richard,

    In that last sentence you said "the custom value is not relevant as it does not utilise the feature in question (and my original script had a typo causing it to fail)." Did you mean that this is working now?  I just tried this on my machine and it appears to work as I would expect:

    Source file: c:\a\web.config

    <configuration>
      <appSettings>
        <add key="test" value="original" />
      </appSettings>
    </configuration>

    Default Config:  c:\default.config

    <configuration>
      <appSettings>
        <add key="test" value="default" />
      </appSettings>
    </configuration>

    Parameters File:  params.xml

    <parameters>
      <parameter name="MyTestParam" description="Test Param" defaultValue="\default.config:://add[@key='test']">
        <parameterEntry kind="XmlFile" scope="web\.config" match="//add[@key='test']" />
      </parameter>
    </parameters>
    

    Command line:
    msdeploy.exe -verb:sync -source:filepath=c:\a\web.config -dest:filepath=c:\b\web.config -setparamfile=params.xml -verbose

    Produces the following file where it replaces the <add> element in the web.config file:  c:\b\web.config

    <configuration>
      <appSettings>
        <add key="test" value="default" />
      </appSettings>
    </configuration>
  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 17, 2012 11:07 PM|richard.szalay|LINK

    Thanks for your help so far and for the article on the parameterization options.

    My only remaining confusion is what the relative file path in "/default.xml::/xpath/query" in relative in relation to? Is it the MSDeploy startup directory? The sync source?

    In addition, if I were to sync to a package would the default value be extracted and stored in the package or would the xml file + xpath be stored in the package and thus potentially point to an unavailable file?

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Dec 18, 2012 11:22 AM|TuesdaysGreen|LINK

    Hi Richard.  The root "\" path is relative to wherever Web Deploy is running on the DESTINATION.  In my case, I was doing a local sync  from "c:\program files\iis\microsoft web deploy v3", so my root would be "c:\".  However, if i was doing a remote sync (using the Web Deployment Agent), the root would be relative to where the Agent Service is installed on the destination computer (which is by default %systemdrive%).  Because of this, I would be careful when thinking whether you want to actually use relative paths or not.

    As for the sync-to-package question, the default value would be stored as the XPath query and not the "discovered" value.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Jan 02, 2013 06:01 PM|richard.szalay|LINK

    Although I can't seem to mark it as the answer, your last response is the information I was lacking.

    Thanks for your help Elliot.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Jul 10, 2013 01:20 AM|snoopdiggy|LINK

    Hey Elliot,

    Thanks, this post is very informative.  I was wondering if there is any way to reference the SOURCE web.config?  

    My use case: I have an element with many nested child elements that I want to parameterize, however, I want the defaultValue to be the same as original element from the source.

  • Re: MSDeploy v3 - xpath-based default parameter values doesn't appear to work

    Jul 10, 2013 04:05 PM|elliott_h|LINK

    Hey there,

    I'm not sure what you mean by wanting the defaultValue to be the same as the original element from the source.  If you want your source web.config to have the same value as the destination web.config file, then you just need to sync it without using parameterization at all.  If you're asking whether you can reference an XML file on the source machine to be used as your default value, then unfortunatley there is no way to accomplish this directly.  

    To get around this, you could include the source XML file in your sync session, or put the source XML file on a file share.  The drawback to including the source file in your session would be that (depending on how you setup your sync), your source XML file could get updated on the destination AFTER parameterization, in which case your default value may not be correct.  One way to gaurantee that the source XML file gets updated first would be to create a manifest that explicitly updates the file you want first, like so:

    <m>
      <contentPath path="site/sourceFile.xml" />
      <contentPath path="site" />
    </m>

    In this case, the first provider will sync the file you want, and then the second provider will sync the content of the entire site.

    Thanks,
    Elliott