none
ForEach-Object passing the $_ variable to commands RRS feed

  • Question

  • I am trying to execute the command c:\Program Files (x86)\GNU\GnuPg\pub\gpg.exe in a ForEach-object

    I set a variable $pgp to the command, then I execute the command with in the ForEach-Object, at least that is what I am trying to do.

    Here is my code:

    cd 'C:\PASSPORT\PSTEST\'

    $pgp='C:\Program Files (x86)\GNu\GnuPg\pub\gpg.exe'

    $pgp

    Get-ChildItem 'C:\Passport\Pstest'|ForEach-Object { If ($_.extension -eq '.txt' ) {& $pgp --always trust -r 'Some key name' -o $_.name+'.gpg' -e $_.name }}

    I am working on Windows Server 2012 R2 64-bit.

    Here the output from my script:

    PS C:\PASSPORT\PStest> cd 'C:\PASSPORT\PSTEST\'

    $pgp='C:\Program Files (x86)\GNU\GnuPg\pub\gpg.exe'

    $pgp

    Get-ChildItem 'C:\Passport\PStest'|ForEach-Object { IF( $_.extension -eq '.txt') { & $pgp --always trust -r 'Passport Health Communications, Inc <netdesk@passporthealth.com>' -o $_.name+'.gpg' -e $_.name }}

    C:\Program Files (x86)\GNU\GnuPg\pub\gpg.exe


    gpg.exe : usage: gpg [options] [filename]

    At line:4 char:84

    + Get-ChildItem 'C:\Passport\PStest'|ForEach-Object { IF( $_.extension -eq

    '.txt') ...

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ~~~

        + CategoryInfo          : NotSpecified: (usage: gpg [options] [filename]:S

       tring) [], RemoteException

        + FullyQualifiedErrorId : NativeCommandError

    gpg.exe : usage: gpg [options] [filename]

    At line:4 char:84

    + Get-ChildItem 'C:\Passport\PStest'|ForEach-Object { IF( $_.extension -eq

    '.txt') ...

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ~~~

        + CategoryInfo          : NotSpecified: (usage: gpg [options] [filename]:S

       tring) [], RemoteException

        + FullyQualifiedErrorId : NativeCommandError

    gpg.exe : usage: gpg [options] [filename]

    At line:4 char:84

    + Get-ChildItem 'C:\Passport\PStest'|ForEach-Object { IF( $_.extension -eq

    '.txt') ...

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ~~~

        + CategoryInfo          : NotSpecified: (usage: gpg [options] [filename]:S

       tring) [], RemoteException

        + FullyQualifiedErrorId : NativeCommandError

    gpg.exe : usage: gpg [options] [filename]

    At line:4 char:84

    + Get-ChildItem 'C:\Passport\PStest'|ForEach-Object { IF( $_.extension -eq

    '.txt') ...

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ~~~

        + CategoryInfo          : NotSpecified: (usage: gpg [options] [filename]:S

       tring) [], RemoteException

        + FullyQualifiedErrorId : NativeCommandError

    I have read every article I can find on executing commands in a foreach-object loop and I have not found the right combination yet.  Any and all help will be appreciated.

    Thank you.

    Monday, November 27, 2017 7:25 PM

Answers

  • I just tested the command and I can't reproduce it:


    & $pgp --always trust -r "Some key name" -o ("{0}.pgp" -f $_.Name) -e $_.Name


    The $_ variable means "current object in the pipeline" which in this case is the object output from Get-ChildItem (i.e., a FileInfo object, which has a Name property that contains the file's name).

    You can also replace


    -o ("{0}.pgp" -f $_.Name)

    with this:


    -o "$($_.Name).pgp"

    But IMO the first one is clearer.


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by Nannylufsu Wednesday, November 29, 2017 9:07 PM
    Wednesday, November 29, 2017 8:25 PM
    Moderator

All replies

  • Try it this way:


    cd "C:\PASSPORT\PSTEST\"
    $pgp = "C:\Program Files (x86)\GNu\GnuPg\pub\gpg.exe"
    Get-ChildItem "C:\Passport\Pstest\*.txt" | ForEach-Object {
      & $pgp --always trust -r 'Some key name' -o ("{0}.pgp" -f $_.Name) -e $_.Name
    }
    

    If you know you always want *.txt, you can put that in the Get-ChildItem command and dispense with the filtering. The -f operator helps us build the filename we want (after -o).

    -- Bill Stewart [Bill_Stewart]


    Monday, November 27, 2017 7:30 PM
    Moderator
  • Bill,

    Thank you for your reply.

    For whatever reason the $_.name variable is not evaluated (I think that is the correct term) to the current file name within the execute statement.  If I take the statement ("{0}.gpg"-f$_.Name)  and use it with the foreach-object it will list the file name in the directory with .gpg appended to the file name.  When I use the $_. variable as parameters for the execution of the pgp program it is like powershell does not recognize the $_. as a variable but as a string.  Does this explanation make sense? 

    Thank you for any help you can give me.

    Wednesday, November 29, 2017 8:03 PM
  • I just tested the command and I can't reproduce it:


    & $pgp --always trust -r "Some key name" -o ("{0}.pgp" -f $_.Name) -e $_.Name


    The $_ variable means "current object in the pipeline" which in this case is the object output from Get-ChildItem (i.e., a FileInfo object, which has a Name property that contains the file's name).

    You can also replace


    -o ("{0}.pgp" -f $_.Name)

    with this:


    -o "$($_.Name).pgp"

    But IMO the first one is clearer.


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by Nannylufsu Wednesday, November 29, 2017 9:07 PM
    Wednesday, November 29, 2017 8:25 PM
    Moderator
  • Bill,

    Thank you for your help. I had another issue with my script, that is why it did not work with your suggestions.

    Here is what I ended up with:

    cd 'C:\Passport\Pstest\'

    Get-ChildItem "C\Passport\Pstest\*.txt" | ForEach-Object {

    & C:\'Program Files (x86)'\GNU\GnuPg\pub\gpg.exe' --always-trust -r "Some Key" -o ("{0}.gpg" -f $-.Name) -e $_.Name

    }

    I greatly appreciate the post you do.  I have learned a lot from them.

    Betty Lou Calloway

    • Marked as answer by Nannylufsu Wednesday, November 29, 2017 9:06 PM
    • Unmarked as answer by Nannylufsu Wednesday, November 29, 2017 9:06 PM
    Wednesday, November 29, 2017 9:06 PM
  • & C:\'Program Files (x86)'\GNU\GnuPg\pub\gpg.exe' ...

    Your quoting of the executable name is a little strange looking; you don't need to quote the individual components in the path. This will work just fine:


    & "C:\Program Files (x86)\GNU\GnuPg\pub\gpg.exe"
    



    -- Bill Stewart [Bill_Stewart]


    Thursday, November 30, 2017 3:00 PM
    Moderator
  • Bill,

    Thank you.  I changed my code to remove the single quotes around the directory name and put double quotes around the complete statement.  Works great.

    Friday, December 1, 2017 2:04 PM