1

I want to use PowerShell to generate a list of commands to move files from one location to another. (I'm sure PowersSell could actually do the moving, but I'd like to see the list of commands first ... and yes I know about -WhatIf).

The files are in a series of subfolders one layer down, and need moved to a corresponding series of subfolders on another host. The subfolders have 8-digit identifiers. I need a series of commands like

move c:\certs\40139686\22_05_2018_16_23_Tyre-Calligraphy.jpg  \\vcintra2012\images\40139686\Import\22_05_2018_16_23_Tyre-Calligraphy.jpg
move c:\certs\40152609\19_02_2018_11_34_Express.JPG   \\vcintra2012\images\40152609\Import\19_02_2018_11_34_Express.JPG

The file needs to go into the \Import subdirectory of the corresponding 8-digit-identifier folder.

The following Powershell will generate the data that I need

dir -Directory |
    Select -ExpandProperty Name |
    dir -File |
    Select-Object -Property Name, @{N='Parent';E={$_.Directory -replace 'C:\\certs\\', ''}}
40139686  22_05_2018_16_23_Tyre-Calligraphy.jpg
40152609  19_02_2018_11_34_Express.JPG
40152609  Express.JPG
40180489  27_11_2018_11_09_Appointment tuesday 5th.jpg

but I am stuck on how to take that data and generate the concatenated string which in PHP would look like this

move c:\certs\$Parent\$Name   \\vcintra2012\images\$Parent\Import\$Name

(OK, the backslashes would likely need escaped but hopefully it is clear what I want)

I just don't know to do this sort of concatenation of columnar output - any SO refs I look at e.g.

How do I concatenate strings and variables in PowerShell?

are not about how to do this.

I think I need to pipe the output to an expression that effects the concatenation, perhaps using -join, but I don't know how to refer to $Parent and $Name on the far side of the pipe?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
DJDave
  • 865
  • 1
  • 13
  • 28

2 Answers2

3

Pipe your output into a ForEach-Object loop where you build the command strings using the format operator (-f):

... | ForEach-Object {
    'move c:\certs\{0}\{1} \\vcintra2012\images\{0}\Import\{1}' -f $_.Parent, $_.Name
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

Another approach:

$source      = 'C:\certs'
$destination = '\\vcintra2012\images'
Get-ChildItem -Path $source -Depth 1 -Recurse -File | ForEach-Object {
    $targetPath = [System.IO.Path]::Combine($destination, $_.Directory.Name , 'Import')
    if (!(Test-Path -Path $targetPath -PathType Container)) {
        New-Item -Path $targetPath -ItemType Directory | Out-Null
    }
    $_ | Move-Item -Destination $targetPath
}
Theo
  • 57,719
  • 8
  • 24
  • 41
  • The OP said they didn't want to do this in PowerShell, but build command strings, so they could run them in another script interpreter. – Ansgar Wiechers Aug 14 '19 at 10:26
  • I'd like to try this as a learning exercise, but not 'live', so where would I put the -WhatIf parameter? Get-ChildItem or Move-Item? – DJDave Aug 14 '19 at 11:29
  • @DJDave `-WhatIf` goes after the `Move-Item -Destination $targetPath`. – Theo Aug 14 '19 at 11:52