Search code examples
powershellcitrixsharefile

Powershell - Rename File and Upload


I have the below script which is working fine for what we need thus far however running into an error as the file names have changed.

With the below script it is providing a Cannot Find Path error as the filenames have changed. Where am i going wrong with this one?

## Add ShareFile PowerShell Snap-in
Add-PSSnapin ShareFile

## Create new authentiation file
#New-SfClient -Name "C:\Sharefile\SVCACC.sfps" -Account midl

## Variables ##
$OutputAppReqFID = "fo4a3b58-bdd6-44c8-ba11-763e211c183f"
$Project = 'M000'
$LocalPath = "\\file.server.au\$project\DATA\DATA CUSTODIAN\OUTPUT\"
$sfClient = Get-SfClient -Name C:\sharefile\SVCACC.sfps
$OutputAppReqFID_URL = (Send-SfRequest $sfClient -Entity Items -id $OutputAppReqFID).Url


## Create PS Drive ##
New-PSDrive -Name "sfDrive-$($project)" -PSProvider ShareFile -Client $sfClient -Root "\" -RootUri $OutputAppReqFID_URL

## Copy all files from folders to ShareFile
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force | Where-Object {$_.Mode -ne "d-----"} | Select FullName -ExpandProperty FullName) { 
     Get-ChildItem $file  -Recurse | Rename-Item -NewName { $_.Directory.Name+'_'+$_.Name}
     Copy-SfItem -Path $file -Destination "sfDrive-$($project):" 
    #remove-item $file
    }

<## Remove all folders from UNC directory
foreach ($folder in Get-childitem -Path $LocalPath -Recurse | Where-Object {$_.Mode -eq "d-----"} | Select-Object -ExpandProperty FullName) {
    remove-item $folder
    }
    #>

## Remove PS Drive ##
Remove-PSDrive "sfdrive-$($project)"

Error recieved is below:

Copy-SfItem : Cannot find path '\\file.server.au\M000\DATA\DATA CUSTODIAN\OUTPUT\New Text Document.txt' because it does not exist.
At line:43 char:6
+      Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (\\file.serve...xt Document.txt:String) [Copy-SfItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,ShareFile.Api.Powershell.CopySfItem

Solution

  • The problem is that you are renaming $file and then trying to Copy-SfItem -Path $file in the very next line. This reference to $file is still pointing to the old name before the rename. You need to instead capture the path to the newly renamed filepath and then reference that in your Copy-SfItem command

    foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force | 
            Where-Object { $_.Mode -ne 'd-----' } | 
                Select-Object -ExpandProperty FullName) {
                    
        # capture reference to the new file name by using -PassThru switch with 
        # the Rename-Item cmdlet and saving in a variable ($renamedFile) 
        $renamedFile = Get-ChildItem $file -Recurse | 
            Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
    
        # Now we copy using our $newFile reference
        Copy-SfItem -Path $renamedFile -Destination "sfDrive-$($project):" 
    
        # followed by removing the file if needed
        # remove-item $renamedFile
    }
    

    This can be cleaned up some as well.

    • Adding the -File switch to Get-ChildItem will give us only files removing the need for | Where-Object {$_.Mode -ne "d-----"}
    • Taking off the | Select-Object -ExpandProperty FullName from the end of the foreach will eliminate the need to calling Get-ChildItem again in the first foreach loop.
    foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force -File ) {
    
        # capture reference to the new file name by using -PassThru switch with 
        # the Rename-Item cmdlet and saving in a variable ($newFile) 
        $renamedFile = $file | Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
    
        # Now we copy using our $newFile reference
        Copy-SfItem -Path $renamedFile -Destination "sfDrive-$($project):" 
    
        # followed by removing the file if needed
        # remove-item $renamedFile
    }
    

    Updates based on your comments

    foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force -File ) {
    
        $file = if ($file.Directory.FullName -ne $LocalPath) {
            # capture reference to the new file name by using -PassThru switch with 
            # the Rename-Item cmdlet and saving in a variable ($file) 
            $file | Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
        }
        else {
            #Pass thru $file with no changes
            $file
        }
    
        # Now we copy using our $file reference
        Copy-SfItem -Path $file -Destination "sfDrive-$($project):" 
    
        # followed by removing the file if needed
        # remove-item $file
    }