Refried04
Refried04

Reputation: 223

Powershell Remove-Item IF file already exists after Copy-item

I need to add a safety net in my script. I'm trying to do a copy job based on a list of users provided through a txt file. Copy the files from that users home directory to a new location. Once the files are copied, check if the file exists in the new location. If yes, then Remove-Item.

Can someone help me? I just don't know how to implement the "if file exists" logic.

$username = Get-Content '.\users.txt'
foreach ($un in $username)
{
  $dest = "\\server\homedirs\$un\redirectedfolders"
  $source = "\\server\homedirs\$un"
  New-Item -ItemType Directory -Path $dest\documents, $dest\desktop

  Get-ChildItem $source\documents -Recurse -Exclude '*.msg' | Copy-Item -Destination $dest\documents
  Get-ChildItem $source\desktop -Recurse -Exclude '*.msg' | Copy-Item -Destination $dest\desktop

  Get-ChildItem $source\mydocuments, $source\desktop -Recurse -Exclude '*.msg' | Remove-Item -Recurse
}

Upvotes: 17

Views: 38956

Answers (4)

Martin
Martin

Reputation: 1

@Adi Inbar, I need to use a function like this because I need to move files to a remote session, and the Move-Item does not work when I tried -ToSession... only Copy-Item. The Key is that if the power or internet goes down, the script will delete the file even if it wasn't copied.

$username = "name"
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential -ArgumentList ($username, $password)
$Session = New-PSSession -ComputerName "IPAdress" -Credential $credential 
Copy-Item -Path C:\userPC_1\csv-output\*.csv  -Destination C:\userPC_2\Documents\Test_Scripts -ToSession $Session -Verbose
Get-PSSession | Remove-PSSession
Get-ChildItem -Path C:\userPC_1\csv-output\*.csv | Remove-Item -Force

Upvotes: 0

majkinetor
majkinetor

Reputation: 9036

The shortest way to delete file if it doesn't exist is NOT to use Test-Path but:

rm my_file.zip -ea ig

This is short version of

rm my_file.zip -ErrorAction Ignore

which is much more readable and more DRY then

if (Test-Path my_file.zip) { rm my_file.zip }

Upvotes: 42

Adi Inbar
Adi Inbar

Reputation: 12323

To answer your question per se, you can do it like this:

Get-ChildItem $source\mydocuments, $source\desktop -Recurse -Exclude '*.msg' | %{
  if (Test-Path ($_. -replace "^$([regex]::escape($source))","$dest")) {
    Remove-Item $_ -Recurse
  }
}
  • Test-Path returns $true if the file at the given path exists, otherwise $false.
  • $_ -replace "^$([regex]::escape($source))","$dest" converts the path of each source item you're enumerating with the corresponding destination path, by replacing $source at the beginning of the path with $dest.
  • The basic regex for the first argument to the -replace operator is ^$source (which means "match the value of $source at the beginning of the string"). However, you need to use [regex]::escape in case $source contains any regex special characters, which is in fact extremely likely with Windows paths, since they contain backslashes. For example, the value you've given here for $source contains \s, which in a regex means "any whitespace character". $([regex]::escape($source)) will interpolate the value of $source with any regex special characters properly escaped, so that you're matching the explicit value.

That said, if your purpose is to copy each item to a new location, and remove the original only if the copy to the new location is successful, it seems like you're reinventing the wheel. Why not just use Move-Item instead of Copy-Item?


Not directly related to the question, but rather than repeating the same command for each subdirectory, you can use a foreach loop:

foreach ($subdir in (echo documents desktop)) {
  # Whatever command you end up using to copy or move the items, 
  # using "$source\$subdir" and "$dest\$subdir" as the paths
}

Upvotes: 7

Knows Not Much
Knows Not Much

Reputation: 31546

Test-Path commandlet will help you check if the file exists

http://technet.microsoft.com/en-us/library/ee177015.aspx

Upvotes: 2

Related Questions