1

I have the below script:

function copyUserSettings {
    Write-Host
    $copyFrom = Read-Host 'Which Folders Do You Want To Copy FROM?'
    Write-Host
    $copyTo = Read-Host 'Which Folders Do You Want To Copy TO? (Enter a Number OR Range eg. 12-18)'
    Write-Host

    IF ($copyTo.Contains("-")) {
        $copyToStart = $copyTo.Split("-")[0]
        $copyToEnd = $copyTo.Split("-")[1]

        $copyToStart..$copyToEnd | foreach{
            Copy-Item -Path $rootPath\FOLDER\$copyFrom\US*.DAT -Destination $rootPath\FOLDER\$_
        }
    } else {
        Copy-Item -Path $rootPath\FOLDER\$copyFrom\US*.DAT -Destination $rootPath\FOLDER\$copyTo
    }
}

The user is supposed to enter where to copy the files from (all the folder names are just a number), and where to copy the files to (also just a number), by entering a single folder name or a range (ie 12-18). If I enter a single number the above script works properly, but if I enter a range the files don't copy and I don't get any feedback error or anything.

Edit1: $rootPath is defined earlier in the script. Edit2: Modified code above per @tnw's suggestion.

Thanks in advance for your help. If you need any more details please let me know.

Lawivido
  • 146
  • 1
  • 1
  • 7

3 Answers3

3

It appears you've misplaced a closing bracket. I've moved that bracket to where it should be (I think). You should exercise better tabbing to avoid these issues:

function copyUserSettings {
    Write-Host
    $copyFrom = Read-Host 'Which Folders Do You Want To Copy FROM?'
    Write-Host
    $copyTo = Read-Host 'Which Folders Do You Want To Copy TO? (Enter a Number OR Range eg. 12-18)'
    Write-Host

    IF ($copyTo -Contains "-") {
        $copyToStart = $copyTo.Split("-")[0]
        $copyToEnd = $copyTo.Split("-")[1]

        $copyToStart..$copyToEnd | foreach {
            Copy-Item -Path $rootPath\FOLDER\$copyFrom\US*.DAT -Destination $rootPath\FOLDER\$_ 
        } #this bracket was missing
    } else {
        Copy-Item -Path $rootPath\FOLDER\$copyFrom\US*.DAT -Destination $rootPath\FOLDER\$copyTo
    }
} #you had an extra closing bracket here

EDIT: Figured it out. Look at this:

"12-18" -Contains "-"

Evaluates to false, so your if never evaluates to true. This is because -Contains is for collections, not substrings. From the documentation: "Tells whether a collection of reference values includes a single test value"

Try this instead:

IF ($copyTo.Contains("-"))

You can also use the -Match operator:

IF ($copyTo -Match "-")
tnw
  • 13,521
  • 15
  • 70
  • 111
  • Thanks for your input. I modified my script with your suggestions, and found an extra bracket towards the bottom somewhere. But unfortunately it still produces the same behavior. Very strange. – Lawivido Sep 18 '13 at 15:40
  • @Fro Have you saved your script? :D just checking. Please double and triple check your brackets... as you had it, your `else` was INSIDE your `if`... which doesnt even make sense! – tnw Sep 18 '13 at 15:41
  • Yes I saved it :D Also modified the script in the original question so you could see where it's at now. – Lawivido Sep 18 '13 at 16:04
  • So...I input 3-6 as the range, and it created a file called 3-6 in the FOLDER folder (if that makes sense), instead of copying all the files to folders named 3..6. – Lawivido Sep 18 '13 at 16:25
  • @Fro Yep, that makes sense. Your `if` never evaluates to `true` so it always falls into the `else`. Try changing your `if` to the code I included in my edit. – tnw Sep 18 '13 at 16:27
  • Hey! You're a genius! It works now. Thanks so much for your persistence with this noob. :) – Lawivido Sep 18 '13 at 16:33
  • @Fro No problem. I have a [post](http://stackoverflow.com/questions/18877580/powershell-and-the-contains-operator) up to try to figure out why `-Contains` behaves like this if you're interested in following up. – tnw Sep 18 '13 at 16:35
  • Looks like @Ansgar Wiechers explained that below. – Lawivido Sep 18 '13 at 18:58
1

The -contains operator checks if a set (e.g. a list/array) contains a particular item. To check if a string contains a particular character you need to use the -like or -match operator:

$copyTo -like '*-*'

$copyTo -match '-'

The -match operator would also allow you to verify if the string contains numbers in the right places and extract those numbers from the string:

if ($copyTo -match '^(\d+)-(\d+)$') {
  $start = $matches[1]
  $end   = $matches[2]
}

Another option would be using the Contains() method of the string class as tnw suggested:

$copyTo.Contains('-')
Community
  • 1
  • 1
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

If I understand your question correctly, $_ is supposed to be destination folder name. But your script doesn't know that so it treats $_ as file name. You need to create destination folders (if they don't exist) and change your Copy-Item destination. Example:

$copyToStart..$copyToEnd | foreach {
    New-Item -Type Directory -Path $rootPath\FOLDER\$_
    Copy-Item -Path $rootPath\FOLDER\$copyFrom\US*.DAT -Destination $rootPath\FOLDER\$_\US*.DAT 
} 
Alexander Obersht
  • 3,215
  • 2
  • 22
  • 26
  • You're correct the $_ is the folder names. But the folders already exist so I shouldn't need to use New-Item. – Lawivido Sep 18 '13 at 16:07