Need a Powershell script to move these files



  • I have a piece of software that gets installed on all tech laptops. That process works.

    But after it is installed, I need to copy a bunch of files into a specific structure.
    The source is always in this format as we centrally download the files and drop them onto a Nextcloud folder that users have access to.
    81fc522a-c030-400c-8b98-25f0ea669cf8-image.png

    So a base folder is
    $basesrcFolder = C:\users\username\nextcloud\folder\subfolder\subfolder\subfolder\

    Sometimes the files are right in the model folder, sometimes they are in more subfolders.
    $basesrcFolder\Model 505D - 8BNCU Truck software file\TPA, LPA\
    $basesrcFolder\Model 914A (8HBE)

    But they need to end up in this base destination folder
    $basedestFolder = C:\Folder\Subfolder

    With a reworked model subfolder
    $basedestFolder\Model505D
    $basedestFolder\Model914A

    The files all have the extension s19 or cbf (cap and non-cap randomly)
    abf1031d-3379-4303-a4ad-1f75cc61c95f-image.png
    1c5db368-82ed-43a0-9854-33aa5e2d0451-image.png
    1a607c2d-a20a-4ff0-80bc-2b6b05835d84-image.png



  • Yes, I can work this out. But I know a few of you are much faster at powershell than I am. If no one can help, I'll work on it tomorrow or Thursday sometime.



  • Do you want ALL the files or just the s19 & cbf files?



  • The script below copies all the files for any folder that matches Model. It searches the whole nextcloud folder.

    <#
    Start with user's nextcloud folder, copy all *folders* that contain $matchString to $destFolder
    
    #>
    
    $baseFolder="$($env:userprofile)\nextcloud"
    
    $matchString="Model"
    
    $destFolder="C:\Folder\"
    
    write-host "Base Folder: $baseFolder"
    write-host "Searching for: $matchString"
    write-host "Destination: $destFolder"
    
    read-host "Press the Enter Key to Continue."
    
    $folderList=get-childitem -path $baseFolder -attributes Directory 
    $folderList=$folderList|where {$_.Name -contains $matchString}
    
    foreach ($item in $folderList) {
        copy-item -recurse -path $item.fullname -Destination "$destFolder\$($item.name)"
    }
    
    


  • With all due to respect, I don't think that script would work.

    help about_comparison_operators states -contains "Returns true when reference value contained in a collection". So it wouldn't apply here. I remember this tripping me up in the past. -match is what you're looking for. Specifically I'd use -imatch for a case-insensitive match.

    And if I may, here are couple other things I'd change.

    I'd join these two lines together:

    $folders = Get-ChildItem -Path $baseFolder -Directory |
        Where-Object -Property Name -imatch $matchString
    

    Rather than manually concatenating the destination path, I'd use the Join-Path cmdlet. And since there are more than two parameters I'd use a splat.

    foreach ($folder in $folders) {
        $copyParams = @{
            Path        = $folder.FullName
            Destination = Join-Path -Path $destFolder -ChildPath $folder.Name
            Recurse     = $true
        }
        Copy-item @copyParams
    }
    

    Hope this helps!



  • And to clarify, I don't think any of this solves the OP's actual problem. That would certainly require more from the script. But I just remember banging my head with -contains in the past and wanted to save some poor soul some time.



  • @bwinc said in Need a Powershell script to move these files:

    Specifically I'd use -imatch for a case-insensitive match.

    All operators are case-insensitive by default, so there's really no general benefit or added value to specifying that. Perhaps you may know of some rare edge case, but generally you don't need to specify. Maybe for readability? Perhaps, I don't see the value in it... in fact, I think it adds negative value as it will more generally confuse another reader of the script. If you want it case-sensitive, then yes, you'll need to prefix the operator with a c, that's a given.



  • @bwinc said in Need a Powershell script to move these files:

    With all due to respect, I don't think that script would work.

    • I tested this before I posted it using my own match string on a folder. It works as expected.

    help about_comparison_operators states -contains "Returns true when reference value contained in a collection". So it wouldn't apply here. I remember this tripping me up in the past. -match is what you're looking for. Specifically I'd use -imatch for a case-insensitive match.

    And if I may, here are couple other things I'd change.

    I'd join these two lines together:

    $folders = Get-ChildItem -Path $baseFolder -Directory |
        Where-Object -Property Name -imatch $matchString
    
    • I generally prefer shorter commands so I can see what happens at each step.

    Rather than manually concatenating the destination path, I'd use the Join-Path cmdlet. And since there are more than two parameters I'd use a splat.

    foreach ($folder in $folders) {
        $copyParams = @{
            Path        = $folder.FullName
            Destination = Join-Path -Path $destFolder -ChildPath $folder.Name
            Recurse     = $true
        }
        Copy-item @copyParams
    }
    
    • Hmm... I like this approach, I may have to look deeper at it.

    Hope this helps!

    • Thanks for the input! 😃


  • @bwinc said in Need a Powershell script to move these files:

    And to clarify, I don't think any of this solves the OP's actual problem. That would certainly require more from the script. But I just remember banging my head with -contains in the past and wanted to save some poor soul some time.

    I butt heads with it every time too, lol. That's why I tested it a couple times before posting it.



  • Going to work on this, finally, after dinner tonight.

    Thanks for those that posted.


Log in to reply