none
Problem sending powershell foreach output to text file RRS feed

  • Question

  • Hello,

    I'm having some trouble outputing a powershell foreach loop to a text file:

    foreach($mbx in Get-Mailbox){Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | select @{n="DisplayName";e={$mbx.displayName}},FolderPath,ItemsInFolder,FolderSize} | Out-File -Append "C:\Exchange_Reports\Deleted_Items.txt"

    I created a blank Deleted_Items.txt document at path specified prior to running the script. However, I run into an empty pipe element error just before the Out-File is run.  If I remove the pipe preceeding the Out-File command, the output is only displayed on-screen and nothing is appended to the Deleted_Items.txt document.

    Can someone help?  Am I missing something simple/obvious here?

    Thanks!

    Sean

    Wednesday, July 23, 2014 3:59 PM

Answers

  • There is no output to the pipeline with a foreach() loop syntax.  It only works with ForEach-Object.

    Try it this way:

    $results=foreach($mbx in Get-Mailbox){
         Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | 
             select @{n="DisplayName";e={$mbx.displayName}},
                    FolderPath,
                    ItemsInFolder,
                    FolderSize
         }
    $results | Out-File C:\Exchange_Reports\Deleted_Items.txt -Append


    ¯\_(ツ)_/¯

    • Marked as answer by s.samuelson Wednesday, July 23, 2014 6:14 PM
    Wednesday, July 23, 2014 4:21 PM

All replies

  • Hi Sean,

    You can't pipe to Out-File when you're not actually in a pipeline. Here's how I'd go about doing something like this:

    $mbxs = Get-Mailbox
    
    $stats = foreach ($mbx in $mbxs) {
    
        Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | 
            select @{n="DisplayName";e={$mbx.displayName}},FolderPath,ItemsInFolder,FolderSize
    
    }
            
    $stats | Sort DisplayName | Export-Csv 'C:\Exchange_Reports\Deleted_Items.csv' -NoTypeInformation


    Don't retire TechNet! - (Don't give up yet - 12,950+ strong and growing)

    Wednesday, July 23, 2014 4:19 PM
  • There is no output to the pipeline with a foreach() loop syntax.  It only works with ForEach-Object.

    Try it this way:

    $results=foreach($mbx in Get-Mailbox){
         Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | 
             select @{n="DisplayName";e={$mbx.displayName}},
                    FolderPath,
                    ItemsInFolder,
                    FolderSize
         }
    $results | Out-File C:\Exchange_Reports\Deleted_Items.txt -Append


    ¯\_(ツ)_/¯

    • Marked as answer by s.samuelson Wednesday, July 23, 2014 6:14 PM
    Wednesday, July 23, 2014 4:21 PM
  • This is how to do it in the pipeline:

    Get-Mailbox | ForEach-Object{
    $mbx=$_ Get-MailboxFolderStatistics $mbx.identity -FolderScope DeletedItems | select @{n='DisplayName';e={$mbx.displayName}}, FolderPath, ItemsInFolder, FolderSize } | Out-File C:\Exchange_Reports\Deleted_Items.txt -Append



    ¯\_(ツ)_/¯


    • Edited by jrv Wednesday, July 23, 2014 4:24 PM
    Wednesday, July 23, 2014 4:23 PM
  • This is how to do it in the pipeline:

    <snip>
    My guess is that Exchange (2010 at least, not sure about 2013) will complain about 'concurrent pipelines' or some garbage. I generally avoid ForEach-Object in the EMS because of that.

    Don't retire TechNet! - (Don't give up yet - 12,950+ strong and growing)

    Wednesday, July 23, 2014 4:25 PM
  • Yes - I know.  It only works in 2013.  2010 and earlier have issues.  The mailbox is opened by the Get-Mailbox and the next CmdLet also wants to open the MB.  The Exchange guys are not real good at designing PowerShell modules.  Part of this is likely because of the strict security and tracking.

    I add the pipeline version as an example knowing that it might fail here.  It is really only to demo the difference.


    ¯\_(ツ)_/¯

    Wednesday, July 23, 2014 4:34 PM
  • Hi Sean,

    You can try using Export-Csv instead of Out-File. It will give you data in csv format which you can edit in Excel easily. Try it this way.

    foreach($mbx in Get-Mailbox)
    {
    Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | select @{ n="DisplayName";e={$mbx.displayName}},FolderPath,ItemsInFolder,FolderSize | Export-Csv "C:\Exchange_Reports\Deleted_Items.csv" -Append
    } 

     

    Wednesday, July 23, 2014 4:38 PM
  • Hi Sean,

    You can try using Export-Csv instead of Out-File. It will give you data in csv format which you can edit in Excel easily. Try it this way.

    foreach($mbx in Get-Mailbox)
    {
    Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | select @{ n="DisplayName";e={$mbx.displayName}},FolderPath,ItemsInFolder,FolderSize | Export-Csv "C:\Exchange_Reports\Deleted_Items.csv" -Append
    } 

     

    Does not solve the problem stated.  The output will be partial due to the placement of the output statement inside of the loop instead of outside.

    On PS 3 and later we can add append to the Export statement but it is still better to aggregate the outout at the beginning or the loop:

    $results = foreach(....){...}

    Then we can export quickly.

    On Exchange 2013 we can just use the pipeline as with other CmdLets.


    ¯\_(ツ)_/¯

    Wednesday, July 23, 2014 4:46 PM
  • There is no output to the pipeline with a foreach() loop syntax. It only works with ForEach-Object.

    You can work around this limitation by enclosing the foreach loop inside a scriptblock; e.g.:


    & {
      foreach ( $item in $collection ) {
        # output items...
      }
    } | export-csv ...
    


    -- Bill Stewart [Bill_Stewart]

    Wednesday, July 23, 2014 6:10 PM
    Moderator
  • Thanks everyone for all the quick responses.  Very helpful.

    I appreciate it.

    Sean

    Wednesday, July 23, 2014 6:18 PM
  • There is no output to the pipeline with a foreach() loop syntax.  It only works with ForEach-Object.

    Try it this way:

    $results=foreach($mbx in Get-Mailbox){
         Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | 
             select @{n="DisplayName";e={$mbx.displayName}},
                    FolderPath,
                    ItemsInFolder,
                    FolderSize
         }
    $results | Out-File C:\Exchange_Reports\Deleted_Items.txt -Append


    ¯\_(ツ)_/¯


    Thank you!  That produced exactly what I was looking for.

    Sean

    Wednesday, July 23, 2014 6:21 PM
  • Cheers, you're welcome.

    I do recommend trying the CSV export that I included in my post instead of using Out-File if you have many mailboxes to churn through. I personally find that it's much easier to just open the output file in Excel and filter it as required as opposed to searching through a text file. Still though, if a text file works for you that's all that matters at the end of the day.


    Don't retire TechNet! - (Don't give up yet - 12,950+ strong and growing)

    Wednesday, July 23, 2014 6:23 PM
  • Cheers, you're welcome.

    I do recommend trying the CSV export that I included in my post instead of using Out-File if you have many mailboxes to churn through. I personally find that it's much easier to just open the output file in Excel and filter it as required as opposed to searching through a text file. Still though, if a text file works for you that's all that matters at the end of the day.


    Don't retire TechNet! - (Don't give up yet - 12,950+ strong and growing)

    Hi Mike,

    Yes, that worked perfectly as well.

    I'll definitely put that to use in the future as we do have a fair amount of mailboxes.  Thanks for that.  And yes, I agree, it's much easier to parse the data within Excel.

    Thanks!

    Sean

    Wednesday, July 23, 2014 6:34 PM
  • There is no output to the pipeline with a foreach() loop syntax.  It only works with ForEach-Object.

    Try it this way:

    $results=foreach($mbx in Get-Mailbox){
         Get-MailboxFolderStatistics $mbx.identity -FolderScope 'DeletedItems' | 
             select @{n="DisplayName";e={$mbx.displayName}},
                    FolderPath,
                    ItemsInFolder,
                    FolderSize
         }
    $results | Out-File C:\Exchange_Reports\Deleted_Items.txt -Append


    ¯\_(ツ)_/¯


    Thank you!  That produced exactly what I was looking for.

    Sean

    Your welcome.  I see you got a lot of new info from everybody.  Good.

    Have a GD.


    ¯\_(ツ)_/¯

    Wednesday, July 23, 2014 7:21 PM