Hashtable to Custom Object

This topic contains 6 replies, has 2 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 2 years, 7 months ago.

  • Author
    Posts
  • #14948
    Profile photo of Clum09
    Clum09
    Participant

    Hello,

    II use a hash table capture the parameter inputs from the PowerShell $args variable and convert this hash table
    to a custom object.

    For some reason the code works fine only if I cast the data from the hash table to the screen first before I
    convert the hash table to the custom object. If I did not cast the data of the hash table to the screen,
    the custom object outputs only one item from the hash table. The code is listed below:

    $cmdLine = $args
    $hash = @{}
    for ($i = 0; $i -lt $cmdLine.Count; $i++) {
    $param = $cmdLine[$i]
    $paramValue = $cmdLine[$i+1]
    switch ($param) {
    {($param -eq '-?') -or ($param -eq '/?')} {
    $hash.Add('Help',$true)
    }
    {($param -eq '-u') -or ($param -eq '/u')} {
    $hash.Add('Username',$paramValue)
    }
    {($param -eq '-f') -or ($param -eq '/f')} {
    $hash.Add('Path',$paramValue)
    }
    }
    }

    # if the line below is commented out only one item is listed by the custom object
    $hash

    if ($hash.count -gt 0) {
    New-Object –TypeName PSObject -Property $hash
    }

    Any comment or help will be appreciated.

    Thanks.

  • #14951
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    What arguments are you passing to this code when you have problems?

    And on a side note, why not just define a parameter block and let PowerShell handle all the parsing for you? That's one of the basic advantages to using PowerShell in the first place, as compared to old command-line utilities and scripts which had to do this sort of thing.

  • #14953
    Profile photo of Clum09
    Clum09
    Participant

    Dave,

    Supposed I have the script saved as Get-Arguments.ps1. I launch the command below to get the folder path, user name, and help info.

    .\Get-Arguments.ps1 -u account -f c:\test -?

    I get the correct custom object output as shown below along with the output from the hash table when I had the $hash line active.

    Name Value
    —- —–
    Username account
    Path c:\test
    Help True

    Username : account
    Path : c:\test
    Help : True

    However, once the $hash line is commented out, I only get only the Username property:

    Username
    ——–
    account

    By the way, below is the output form $PSVersionTable:
    Name Value
    —- —–
    PSVersion 4.0
    WSManStackVersion 3.0
    SerializationVersion 1.1.0.1
    CLRVersion 4.0.30319.18408
    BuildVersion 6.3.9600.16406
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
    PSRemotingProtocolVersion 2.2

    Thanks.

  • #14954
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Odd. Your code works fine for me, with both the script and the command to call it copied and pasted from your posts. I'm also running PowerShell 4.0.

    Here's how I would do it, eliminating the need to roll your own parsing code:

    [CmdletBinding()]
    param (
        [string]
        $Path,
    
        [string]
        $UserName,
    
        [switch]
        $Help
    )
    
    # If you want to convert the command-line arguments to an object for some reason at this point,
    # the $PSBoundParameters variable is already a dictionary:
    
    New-Object -TypeName PSObject -Property $PSBoundParameters
    

    On another side note, the -Help or /? switch isn't really in keeping with usual PowerShell practices; that's another old approach used for console applications. In PowerShell, I would instead define a comment-based help block for your script or function, and users would call Get-Help on that command when they need to.

  • #14955
    Profile photo of Clum09
    Clum09
    Participant

    The parameter block you suggested works fine with the plain .ps1 file. However, when the script is packaged by a script editor
    like PrimalScript or other script editors, it does not work.

    That was the reason why I had resort to the old $args PowerShell variable.

    By the way, when I tried to use the $PSBoundParameters variable in my script, I got no output.
    What Operating System are you running this under?

  • #14956
    Profile photo of Clum09
    Clum09
    Participant

    Never mind for my comment about $PSBoundParameters. The code below works, but again only one output from the
    command line even if I entered the command line as Get-Arguments.ps1 -username account -path c:\test.

    UserName
    ——–
    account


    [CmdletBinding()]
    param (
    [string]
    $Path,
    [string]
    $UserName,
    [switch]
    $Help
    )
    New-Object -TypeName PSObject -Property $PSBoundParameters

  • #14957
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    If you're using some tool to package the script to exe, or something like that, you'll probably have to contact the vendor for that tool. I've only done that once, at a customer's request, and I forget which tool they used. I do remember that an extra command-line argument had to be used when running the packaged version (something like MyPackagedScript.exe -Arguments -UserName account -Path c:\path -Help . Everything after -Arguments was passed to the underlying script after it was extracted.)

You must be logged in to reply to this topic.