views:

1608

answers:

2

I am new to PS. Here is an example of my function codes:

function foo() 
{
    # get a list of files matched pattern and timestamp
    $fs = Get-Item -Path "C:\Temp\*.txt" | Where-Object {$_.lastwritetime -gt "11/01/2009"}
    if ( $fs -ne $null ) # $fs may be empty, check it first
    {
      foreach ($o in $fs)
      {
         # new bak file
         $fBack = "C:\Temp\test\" + $o.Name + ".bak"
         # Exception here Get-Item! See following msg
         # Exception thrown only Get-Item cannot find any files this time.
         # If there is any matched file there, it is OK
         $fs1 = Get-Item -Path $fBack
         ....
       }
     }
  }

The exception message is "The WriteObject and WriteError methods cannot be called after the pipeline has been closed. Please contact Microsoft Support Services."

Basically, I cannot use Get-Item again within the function or loop to get a list of files in a different folder. Not sure why. Any explanation and what is the correct way to fix it?

By the way I am using PS 1.0.

+1  A: 

Hi,

I modified the above code slightly to create the backup file, but I am able to use the Get-Item within the loop successfully, with no exceptions being thrown. My code is:

 function foo() 
 {
     # get a list of files matched pattern and timestamp
     $files = Get-Item -Path "C:\Temp\*.*" | Where-Object {$_.lastwritetime -gt "11/01/2009"}
     foreach ($file in $files)
     {
        $fileBackup = [string]::Format("{0}{1}{2}", "C:\Temp\Test\", $file.Name , ".bak") 
        Copy-Item $file.FullName -destination $fileBackup
        # Test that backup file exists 
        if (!(Test-Path $fileBackup))
        {
             Write-Host "$fileBackup does not exist!"
        }
        else
        {
             $fs1 = Get-Item -Path $fileBackup
             ...
        }
     }
 }

I am also using PowerShell 1.0.

MagicAndi
not really the case of miss-spelling. I correct the codes. Mine still does not work. Not sure the case of $fileBackup containing spaces would cause the problem. My test case gets $fileBackup with "C:\temp\copyof test file.txt.bak"
David.Chu.ca
David, apologies for the incorrect file path of the backup file. I have updated my answer.
MagicAndi
OK. I see the problem. I don't have backup file in the destination. Get-Item second time will throw exception when it is empty. If you remove Copy-Item ... and make sure no files is there in dest, you will see the exception. The problem is that the first time Get-Item can be empty or null, but not the second time. Right? I edited my codes again to reflect the issue.
David.Chu.ca
I think I find out the reason and a solution. In the call of "Get-Item -Path $var", $var either has to be a valid path (existing) or file patten with wild chars like "*" or "?". Otherwise, exception will be thrown. In my case, the code should be something like: Get-Item -Path "C:\Temp\Test" | Where-Object {$_.FullNam -like $fileBackup. This one is OK as well: Get-Item -Path "C:\Temp\Test\*.bak". Both return empty or list of files.
David.Chu.ca
David, I have added a check in my code to make sure that the backup file exists before I attempt to retrieve it with the Get-Item call. I make use of the in-built Test-Path method in PowerShell.
MagicAndi
+2  A: 

This is just a minor variation of what has already been suggested but it uses some techniques that make the code a bit simpler:

function foo() 
{    
    # Get a list of files matched pattern and timestamp    
    $fs = @(Get-Item C:\Temp\*.txt | Where {$_.lastwritetime -gt "11/01/2009"})
    foreach ($o in $fs) {
        # new bak file
        $fBack = "C:\Temp\test\$($o.Name).bak"
        if (!(Test-Path $fBack))
        {
            Copy-Item $fs.Fullname $fBack
        }

        $fs1 = Get-Item -Path $fBack
        ....
    }
}

For more info on the issue with Foreach and scalar null values check out this blog post.

Keith Hill
Keith, gets my vote. +1 for a cleaner implementation.
MagicAndi