Answered Build a variable name

  • Monday, February 25, 2013 6:49 PM
     
      Has Code

    I have a script

    [xml]$XmlData = Get-Content $XmlDataFile
    $Data = $XmlData.TData.Type18.Job | %{
    	New-Object PSObject -Property @{
    		id		= $_.id
    		DataSetName	= $_.DataSetName
    		Job	= $_.Job
    	}
    }

    This works fine.

    However I want to be able to "build" the variable name, IE

    [xml]$XmlData = Get-Content $XmlDataFile
    $Number=18
    $VarName = "XmlData.TData.Type"+$Number+".Job"
    $Data = $($VarName) | %{
    	New-Object PSObject -Property @{
    		id		= $_.id
    		DataSetName	= $_.DataSetName
    		Job	= $_.Job
    	}
    }

    And get the same results.  I can't seem to get the syntax right.  Can anyone steer me in the right direction?



    • Edited by DennisT. _ Monday, February 25, 2013 6:50 PM
    • Edited by DennisT. _ Monday, February 25, 2013 6:51 PM fix typos
    •  

All Replies

  • Monday, February 25, 2013 7:19 PM
     
     

    I'm a bit confused here. what, precisely, does the assignment statement send to the pipeline?

    It also seems that you do not want to "build a variable name", but "make the name of a property in a property reference variable". Thinking the latter, I think you need to consider invoke-expression. Take note of example 1 here: help invoke-expression -detailed.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

  • Monday, February 25, 2013 7:22 PM
    Moderator
     
      Has Code

    (get-variable variableName).Value

    might get you where you need to go.

    Bill

  • Monday, February 25, 2013 8:01 PM
     
      Has Code

    The xml file contents would be something like this:

    <?xml version="1.0" standalone="yes"?>
    <TData>
    	<Type18>
    		<Host id="System1">
    			<DataSetName>SYS1</DataSetName>
    			<Job>COPY</Job>
    		</Host>
    		<Host id="System2">
    			<DataSetName>SYS2</DataSetName>
    			<Job>MOVE</Job>
    		</Host>
    		<Host id="System3">
    			<DataSetName>SYS3</DataSetName>
    			<Job>PURGE</Job>
    		</Host>
    	</Type18>
    </TData>

    The script (slight error in my original script corrected here):

    [xml]$XmlData = Get-Content $XmlDataFile
    $Data = $XmlData.TData.Type18.Host | %{
    	New-Object PSObject -Property @{
    		id		= $_.id
    		DataSetName	= $_.DataSetName
    		Job	= $_.Job
    	}
    }

    creates a object with the contents of the xml data in an array, IE $Task[0].Job is "COPY"

    I need to dynamically create the XmlData.TData.Type18.Host string and use it as a reference to access the data it represents.    I've tried get-variable (says it isn't a variable).  I tried invoke-expression but haven't been able to get any results (not really sure how it would work in this case).

  • Monday, February 25, 2013 8:01 PM
    Moderator
     
     
    Any time I've started down that path, it always got easier when I gave up on that idea and used a hash table instead.....

    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "

  • Monday, February 25, 2013 8:10 PM
    Moderator
     
     Proposed Answer Has Code

    This worked for me:


    [Xml] $XmlData = Get-Content $XmlDataFile
    $number = 18
    $typeString = "Type{0}" -f $number
    $XmlData.TData.$typeString.Host | %{
      New-Object PSObject -Property @{
        id = $_.id
        DataSetName = $_.DataSetName
        Job = $_.Job
      }
    }

    Bill

  • Monday, February 25, 2013 8:40 PM
     
     
    If I do the above I don't get any results, IE $Data[0].Job returns nothing.  (I assume you meant $Data = $XmlData.TData.$typeString.Host | %{ )
  • Monday, February 25, 2013 8:46 PM
    Moderator
     
     

    That is correct. My script example output the object directly for purposes of demonstrating that it works. If you need to store the object in a variable, by all means, feel free to do that.

    Bill

  • Monday, February 25, 2013 8:52 PM
     
     

    Using the xml data I posted above I get:

    id                                                            DataSetName                                          Job                                                          
    --                                                            -----------                                                   ---

    and no actual data

    If I use $XmlData.TData.Type18.Host instead I get:

    id                                                            DataSetName                                                   Job                                                          
    --                                                            -----------                                                   ---                                                          
    System1                                                       SYS1                                                          COPY                                                         
    System2                                                       SYS2                                                          MOVE                                                         
    System3                                                       SYS3                                                          PURGE

  • Monday, February 25, 2013 9:11 PM
    Moderator
     
     Answered Has Code

    I copied and pasted your XML data and saved it to C:\Temp\test.xml

    Next I created a PowerShell script file, C:\Temp\test.ps1, that contains only the following lines:


    $XmlDataFile = "C:\Temp\Test.xml"
    [Xml] $XmlData = Get-Content $XmlDataFile
    $number = 18
    $typeString = "Type{0}" -f $number
    $XmlData.TData.$typeString.Host | foreach-object {
      New-Object PSObject -Property @{
        id = $_.id
        DataSetName = $_.DataSetName
        Job = $_.Job
      }
    }
    

    Finally, I ran the script from the PowerShell prompt to see its output:


    PS C:\> C:\Temp\test.ps1 | format-list
    id          : System1
    DataSetName : SYS1
    Job         : COPY
    
    id          : System2
    DataSetName : SYS2
    Job         : MOVE
    
    id          : System3
    DataSetName : SYS3
    Job         : PURGE
    

    I piped to format-list, but that only formats the output; it does not change the output.

    All I did was write a very short script that demonstrates a sample of how to accomplish your goal. You can use the same technique I used in this demo script in your own script.

    Bill

  • Monday, February 25, 2013 9:35 PM
     
      Has Code

    Bill,

    Got it!  I wasn't using the foreach.

    I did some testing using hashtables.  Something I hadn't used in powershell before.  I found the following seems to work and is definitely shorter:

    [xml]$XmlData = (Get-Content $XmlDataFile)

    $Num=18 $TypeStr="Type"+$Num $Data=$XmlData.TData.$TypeStr.SelectNodes("//Host")