0

I am attempting to write a Powershell script to do an incremental differential backup of my computer, however I am having issues with how Powershell is interpreting file path variables.

$C_P86Files_Name=Get-ChildItem -File -Path 'C:\Program Files (x86)\Test' -Recurse | foreach FullName
$B_P86Files_Name
$MovedFiles=0
$MovedBytes=0

#Out-File -FilePath 'C:\Program Files (x86)\Test\Test.txt' -InputObject $C_P86Files_Name

Get-ChildItem -File 'C:\Program Files (x86)\Test' -Recurse | foreach FullName

for ($i=0; $i -le ($C_P86Files_Name.Length-1); $i++)
{
    $B_P86Files_Name = $C_P86Files_Name[$i] -replace "^C", "B"

    Write-Host "Checking $($C_P86Files_Name[$i])"
    Write-Host "B drive directory: $($B_P86Files_Name[$i])"

    if(((ls $C_P86Files_Name[$i]).LastWriteTime -ne (ls $B_P86Files_Name[$i]).LastWriteTime) -or ((Test-Path $C_P86Files_Name[$i]) -and (!(Test-Path $B_P86Files_Name[$i]))))
    {
        Copy-Item $C_P86Files_Name[$i] -Destination $B_P86Files_Name[$i]
        $MovedFiles++;
        $MovedBytes+=(Get-Item $C_P86Files_Name[$i]).length

        Write-Host "Moved $($C_P86Files_Name[$i]) to $($B_P86Files_Name[$i])"
    }
}

Write-Host "Total data moved: $($MovedBytes)"

The output ends up showing that instead of iterating through C:\Program Files (x86)\Test, it tried iterating through each letter of that path as though it were a file, and then erroring out accordingly (e.g. it checks "C" and then checks ":" and then checks "\" and so forth).

I tried adding escaped quotes to the variables in the IF statement, but this did not effect anything.

The outfile does show a correct filepath, so it seems to get the correct information. What I don't understand is why the array $C_P86Files_Name appears to use each character from the path as an index in the array instead of each filer from Get-ChildItem as an index in the array?

0

If you treat a (single) string as an array it will use an index as a char pointer, to prevent this use @() to force an array even with only 1 element.

Your usage of:

Get-ChildItem -File 'C:\Program Files (x86)\Test' -Recurse | foreach FullName

Returns a string/an array of strings.

It would be much easier keeping them as an object you could iterate through (and still have access to it's properties)

$C_P86Files = Get-ChildItem -File -Path 'C:\Program Files (x86)\Test' -Recurse
ForEach ($File in $C_P86Files){
    $B_FullName = $File.FullName -Replace '^C','B'
}
0

Got past this issue. Seems as though another variable needs to be declared in order for the array to have one line per index instead of one character.

$Files=Get-ChildItem -File -Path "C:\Program Files (x86)\Test" -Recurse | Select-Object -ExpandProperty FullName
$C_P86Files_Name
$B_P86Files_Name
$MovedFiles=0
$MovedBytes=0
Out-File -FilePath "C:\Program Files (x86)\Test\Test.txt" -InputObject $Files

'-----------------------------------------------------------------'

$C_P86Files_Name=$Files
$B_P86Files_Name=$Files

foreach($i in $C_P86Files_Name)
{
    $C_P86Files_Name[$i]
}

for ($i=0; $i -le ($C_P86Files_Name).Length; $i++)
{
    $B_P86Files_Name[$i]=$B_P86Files_Name[$i] -replace "^C", "B"

    Write-Host "C drive directory: $($C_P86Files_Name[$i])"
    Write-Host "B drive directory: $($B_P86Files_Name[$i])"

    if(((ls $C_P86Files_Name[$i]).LastWriteTime -ne (ls $B_P86Files_Name[$i]).LastWriteTime) -or ((Test-Path $C_P86Files_Name[$i]) -and (!(Test-Path $B_P86Files_Name[$i]))))
    {
        Copy-Item $C_P86Files_Name[$i] -Destination $B_P86Files_Name[$i]
        $MovedFiles++;
        $MovedBytes+=(Get-Item $C_P86Files_Name[$i]).length

        Write-Host "Moved $($C_P86Files_Name[$i]) to $($B_P86Files_Name[$i])"
    }
}

Write-Host "Total data moved: $($MovedBytes)"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.