none
Read variables from XML RRS feed

  • General discussion

  • Is it somehow possible to read variables and values from xml into an PowerShell script without specifying each of them separately?

    For example I've set the following variables:

    $arrPostcode @()
    $arrPostcode += ,@('1234AB', 'City1')
    $arrPostcode += ,@('4567CD', 'City2')
    $blnHome =$True
    $blnNld =$False
    $intNumbers =556
    $strText ='Something'

    And I have a xml file like (can be ajusted when required to get a better result):

    <?xml version="1.0"?>
    <Objects>
      <Object Type="System.Management.Automation.PSVariable">
        <Property Name="Name" Type="System.String">arrPostcode</Property>
        <Property Name="Value" Type="System.Object[]">
          <Property Type="System.Object[]">
            <Property Type="System.String">9874ZX</Property>
            <Property Type="System.String">City5</Property>
          </Property>
          <Property Type="System.Object[]">
            <Property Type="System.String">6541UH</Property>
            <Property Type="System.String">City3</Property>
          </Property>
        </Property>
        <Property Name="ModuleName" Type="System.String" />
      </Object>
      <Object Type="System.Management.Automation.PSVariable">
        <Property Name="Name" Type="System.String">blnHome</Property>
        <Property Name="Value" Type="System.Boolean">False</Property>
      </Object>
      <Object Type="System.Management.Automation.PSVariable">
        <Property Name="Name" Type="System.String">blnNld</Property>
        <Property Name="Value" Type="System.Boolean">True</Property>
      </Object>
      <Object Type="System.Management.Automation.PSVariable">
        <Property Name="Name" Type="System.String">intNumbers</Property>
        <Property Name="Value" Type="System.Int32">13</Property>
      </Object>
      <Object Type="System.Management.Automation.PSVariable">
        <Property Name="Name" Type="System.String">strText</Property>
        <Property Name="Value" Type="System.String">World</Property>
      </Object>
    </Objects>
    And say I want to use the 'default' values if the xml file was not found, but if the xml file is found I want to use (replace) the variables and values defined in that xml file.



    Friday, October 31, 2014 8:21 AM

All replies

  • First of all your sample code I not PowerShell.  Second XML has no "variables".  It is a structured document.  When imported into PowerShell it shows up as an XMLDocument object.  If you want values from the document you have to extract them by direct reference or query.

    The simple answer to your question is "yes".  You can assign a default to a variable which will be updated only if the value exist in the document.  The rest cannot be determined from what you have asked.

    Start by learning some of the basics of PowerShell scripting and ask a new question when you can see what it is you want to do.

    Here is a good starting point: http://technet.microsoft.com/en-us/scriptcenter/dd793612.aspx

    The XML you have posted is actually PowerShell object serialization format so it is already a PS object.  It is not just arbitrary XML.  It isnot clear howyou acquired this which is another reason to learn more of the PS basics. 

    It appears that you have used ConvertTo-XML to create an XML object.  This can be sued to dave values and state but may not bethe best method.  Export-CliXml can persist an object and restore it more directly.  We can wrap this in a function that can be used to default values.

    Look into Export.CliXml and Import-CliXml.

    Example:

    $ziptable=@()
    $myProps=@{
      Name='Detroit'
      ZipCode='20192'
    }
    $ziptable+=New-Object PsObject -Property $myProps
    $myProps=@{
      Name='New York'
      ZipCode='90100'
    }
    $ziptable+=New-Object PsObject -Property $myProps
    
    $ziptable | Export-CliXml myzips.clixml
    
    $savezips = Import-CliXml myzips.clixml


    Result demo:

    PS C:\scripts> $savezips
    
    ZipCode                                                     Name
    -------                                                     ----
    20192                                                       Detroit
    90100                                                       New York
    
    
    PS C:\scripts> $savezips[0]
    
    ZipCode                                                     Name
    -------                                                     ----
    20192                                                       Detroit
    PS C:\scripts> $savezips[0].Zipcode
    20192
    PS C:\scripts>

    Of course a simple lookup table would be done with a pure hash and persisted.  For more comples things I would use a custom dataset which can also be persited and restored the same way.  Sort of a poor man's portable database.


    ¯\_(ツ)_/¯




    • Edited by jrv Friday, October 31, 2014 9:30 AM
    Friday, October 31, 2014 9:27 AM
  • Thank you for your reply.

    Indeed the variables were wrong (copy paste error), I changed it.

    The XML was indeed generated by ConvertTo-XML, it was something I tried. But If you suggest a better XML layout for my question?

    To clarify a bit more, I'm creating a script with allot of variables (array, string, integer, boolean). A user can edit the script set the variables and then run the script.

    But I prefer that the user only need to change a file (for example a XML file or any other file, open for suggestions) to set the variables and then run the script. But when there is no file it uses the "default" values specified in the script.

    I will have a look into the Export.CliXml and Import-CliXml and see if this is what I need.

    Friday, October 31, 2014 2:18 PM
  • It appears that you have a design problem.  When we want to load a set of variables in a program it is usually don by passing arguments on a command line.

    If you are taling about a configuration file then there are mnay ways to do that.  YOU can start with a set of embeddd variables or structures and overwrite with this from a file.

    Exactly what you are doing is vague.  Wirhout a good example and a reason for the idea it is not really possible to give any kind of answer.

    You can also just use a pairs file.

    Name=Value

    Example:

    Janyuary=1
    February=3
    March=3
    Apreil=4

    We can then load this like this:

    # create default values
    Get-Content defaults.config |

         ForEach-Object{
              $name,$Value=$_.Split('=')
              New-Variable $name $value
    }

    Get-Content user.conf |
         ForEach-Object{
              $name,$Value=$_.Split('=')
              Set-Variable $name $value
    }

    Now we have loaded the variables.

    Defaults are loaded first then thee user overrides.  If the user doesn't define a value the default file has already specified it.

    It all depends on the purpose which is unknown at this time.

    Using XML is really not a good choice from all that you have posted so far.


    ¯\_(ツ)_/¯

    Friday, October 31, 2014 3:22 PM
  • Thank you for your answers.

    I'm fairly new to PowerShell scripting. And I've done some scripting before with other languages and used for example INI files.

    But this time I wanted to use the PowerShell scripting language because of the type of script. It's a script to optimize vdi environments. This script has a lot of parameters. To many to specify in a commandline. It also needs to be a script what can be used in SCCM for automatic deployments. I've already got the script and it is functioning just right.

    And because every environment is different the script can be adjusted to the specifications needed. Now every time you need to edit the script to change the parameters. And thus I was wondering if it was somehow possible to easily create a file that the script can pick-up and read everything. And if no config file is specified or found it will use the default values. So just seeing if it's possible.

    And because PowerShell can read XML's by default I was thinking to use XML. Also because of the different types of variables used like array's strings booleans and integers. And maybe in a later stadium create a GUI that can create and or edit the config file...

    But I think I'm thinking to complicated...

    Friday, October 31, 2014 9:14 PM
  • Again you need to rethink your design.  Perhaps you are overcomplicating things.  I it absolutely necessary to have configuration variables strongly typed.  After all this is a script.

    CliXml will do this and save and load easily.   Look into it but I suspect it is overkill.


    ¯\_(ツ)_/¯

    Friday, October 31, 2014 9:26 PM