ForEach not working with table output, but does work with impot-csv. Help?

Tagged: ,

This topic contains 7 replies, has 3 voices, and was last updated by Profile photo of Joshua Barton Joshua Barton 9 months, 1 week ago.

  • Author
    Posts
  • #35542
    Profile photo of Jay4096
    Jay4096
    Participant

    Im trying to pull a list of all printers on a server, run the list though an array, pass the list into some regex and than into subinacl to add a group. I have replaced subinacl with echo to verify the regex path is correct.. and its not. (im using subinacl because SDDL only mirrors/overwrites permissions, and we have alot of printers with custom permissions)

    Here I am using import-csv, and it works fine

    Import-Csv .\THS-Printers2.csv | foreach {
    $Path1 = "PRNTR"
    $Path2 = $_.Header
    $NewPath = "\\ktthsprn02\PRNTR"
    $NewSharePath = $NewPath –Replace ([regex]::Escape("$Path1"),"$Path2")
    Echo $NewSharePath
    }
    

    ——————–

    I'm trying to get away from csv for simplicity and using get-printer -computer server.....
    (im using "% { if ( $_ -ne $null ) { $_.name } }" instead of "ft -hidetableheaders -prop name" to remove any blank lines).

    Here the code is almost identical to the code above, but instead of passing the data using import-csv I wanted to use the output of get-printer. But the output is blank.

    $list = (get-printer -computer ktthsprn02 |  % { if ( $_ -ne $null ) { $_.name } })  | foreach {
    $Path1 = "PRNTR"
    $Path2 = $list
    $NewPath = "\\ktthsprn02\PRNTR"
    $NewSharePath = $NewPath –Replace ([regex]::Escape("$Path1"),"$Path2")
    Echo $NewSharePath
    }

    I also tired this (below), but get "Unexpected token 'in' in expression or statement."

    $list = (get-printer -computer ktthsprn02 |  % { if ( $_ -ne $null ) { $_.name } })  | foreach ($prn in $list) {
    $Path1 = "PRNTR"
    $Path2 = $prn
    $NewPath = "\\ktthsprn02\PRNTR"
    $NewSharePath = $NewPath –Replace ([regex]::Escape("$Path1"),"$Path2")
    Echo $NewSharePath
    }

    Any help would be appreciated! Thank you

  • #35543
    Profile photo of Don Jones
    Don Jones
    Keymaster

    That is because $PATH2 is a collection of objects. In your CSV example, $PATH2 is a String, which you created by taking the "header" column of the current CSV row. You used a ForEach to process each CSV row; you did not take the same approach for the Get-Printer version.

    You probably meant to set $Path2 = $_, which is the printer name you fed into the ForEach loop. As is, you've set it to $list, which isn't anything at that point. $list will eventually be whatever is output from the ForEach loop.

    In your second example, $Path2 = $prn.name would probably have worked.

  • #35555
    Profile photo of Jay4096
    Jay4096
    Participant

    Thank you for the tips. I realized what I was doing wrong. (sometimes I get tunnel vision.)
    I was making this more complicated than necessary, and did not need to format the output of get-printers because that's the whole point of powershell tables and objects... Now I see why $_ is needed and learned something rather than just using it! 🙂

    If anyone wants to know, here is what worked:
    (I used a "3rd" party tool, subinacl because I don't think the cmdlet "set-acl" works with printers. If I'm wrong please correct me.)

    get-printer -computer PRINTSERVER | foreach {
    $Path1 = "PRNTR"
    $Path2 = $_.Name
    $ModifiedPath = "\\PRINTSERVER\PRNTR"
    $NewPath = $ModifiedPath –Replace ([regex]::Escape("$Path1"),"$Path2")
    .\subinacl.exe /printer $NewPath /Grant=DOMAIN.org\GROUP=F
    }

    Thanks!

  • #35567
    Profile photo of Joshua Barton
    Joshua Barton
    Participant

    I'm purely curious, why do you do:

    $Path1 = "PRNTR"
    $Path2 = $_.Name
    $ModifiedPath = "\\PRINTSERVER\PRNTR"
    $NewPath = $ModifiedPath –Replace ([regex]::Escape("$Path1"),"$Path2")
    

    instead of something like:

    $PrinterName = $_.Name
    $PrinterPath = "\\PRINTSERVER\$PrinterName"
    

    Why the more complicated regex replacement?

  • #35576
    Profile photo of Jay4096
    Jay4096
    Participant

    We have eight print servers so eventually "printserver" will become "$printserver" and when you do:

    \\$printserver\$_.name

    you get funky output and it didn't work.
    Escape characters didn't really work with variables either. So I found that regex did work, and I stopped there because it worked fine. If you know of a better way please post it.

  • #35578
    Profile photo of Joshua Barton
    Joshua Barton
    Participant

    I don't think it's the $printserver that is causing your issue. Assuming you mean "\\$printserver\$_.name", I would not be surprised the output was unexpected. Using a property in quotes will not result in the value of the property. You could use $($_.Name). Or you could do what I pointed out and push the property into the value of $PrinterName. In other words, assuming I understand what you're trying to do, the code would look something like this:

    Foreach ($PrintServer in $PrintServers)
    {
        Get-Printer -Computer $PrintServer | ForEach-Object {
            $PrinterName = $_.Name
            $PrinterPath = "\\$PrintServer\$PrinterName"
            .\subinacl.exe /printer $PrinterPath /Grant=DOMAIN.org\GROUP=F
        }
    }
    

    The other way I mentioned that should work would be this:

    Foreach ($PrintServer in $PrintServers)
    {
        Get-Printer -Computer $PrintServer | ForEach-Object {
            $PrinterPath = "\\$PrintServer\$($_.Name)"
            .\subinacl.exe /printer $PrinterPath /Grant=DOMAIN.org\GROUP=F
        }
    }
    
  • #35591
    Profile photo of Jay4096
    Jay4096
    Participant

    Thanks! The quotes got me

    Its the little things that I don't think about that ends up getting me.. There is so many different ways many ways to cut a sandwich.. Sometimes I use the butter knife before I can find the right one!

  • #35631
    Profile photo of Joshua Barton
    Joshua Barton
    Participant

    No problem! I'm glad I could help! 🙂

You must be logged in to reply to this topic.