1

I have for now a fixed list of items that need to be "backuped" and afterwards played back to their origin path.

It has to be done "complex" so

copy from a to b
do some stuff
copy from b to a

isn't allowed

I was thinking about to achive this with a "list of items" that is either aquired through a csv-import or a pre determind arraylist.

But i'm stuck with the part to get stuff back to their origin place while achiving this.

code actually looks like this atm.

function Backup-2Temp ($items, $Temp){ 
    foreach ($item in $items){
        Copy-Item -Path $item -Destination "$Temp"
        <#
        Create Array with the filename and originpath
        $pathremind = @(
            += "$itemname" "$originpath"
        )
        #>
    }
    return $pathremind
}
function Restore-Temps($premind,$Temp){
$TempItems = Get-ChildItem -Path $Temp
    foreach($item in $premind){
        |where $item.name -EQ $TempItems.Name
    copy-item -Path "itemTemppath" -Destination $item.originpath
    }
}

$items2copy = @(
    "$testpath\DeviceSettings.ini",
    "$testpath\otc.ini"
)

$user = Read-Host "which User will be reseted"
$Temp = "C:\Users\$user\AppData\Roaming\testTemp"
$testpath = "C:\Users\$user\AppData\Roaming\test"
create-folder -path $Temp
$premind = Backup-2Temp $items2copy $Temp
Remove-Item -Path $testpath -Recurse
Restore-Temps
Remove-Folder $Temp

This explains how I was thinking about it. But I made it to complex for my Brain to get it done properly atm. And I can't figure out how to solve this mess now.

I don't need you to do my work tho. I'm just searching for any kind of help to get my mess readable again or better said correct and understandable.

Sry for the big mess here.

Edit 1:

Playing around with the "Get-Something" as mentiond in the answers. But either way I'm turning around the puzzle pieces. I won't get any data out of Get-Something my return is null everytime.

Edit 2:

Found out was missing the '-passthru', still searching for the "originpath" how to put it all together.

Edit 3:

As there was mentiond the Custom Object I had a new clue and come to this

function Backup-2Temps ($myitems){
    foreach($item in $myitems){
        Copy-Item -Path "$item.originpath\$item.name" -Destination $item.Temppath -PassThru
    }
}
function Restore-Temps($myitems){
    foreach($item in $myitems){
        Copy-Item -Path "$item.Temppath\$item.name" -Destination $item.originpath -PassThru
    }
}

$user = Read-Host "which User will be reseted"
$testpath = "C:\Users\$user\AppData\Roaming\test"
$otherpath = "C:\Users\$user\AppData\Roaming\testo"
$p2Temp = "C:\Users\$user\AppData\Roaming"
$Tempn = "testT"

New-Item -Path $p2Temp -Name $Tempn -ItemType "directory"
$Temp = "$p2Temp\$Tempn"

$myitems = @(
[pscustomobject]@{name="Device.txt"; originpath = $testpath; Temppath = $Temp},
[pscustomobject]@{name="otc.txt"; originpath = $testpath; Temppath = $Temp},
[pscustomobject]@{name="test.txt"; originpath = $otherpath; Temppath = $Temp}
)

Backup-2Temps $myitems
Remove-Item -Path $testpath -Force -Recurse
Remove-Item -Path $otherpath -Force -Recurse
New-Item -Path $p2Temp -Name "test" -ItemType "directory"
New-Item -Path $p2Temp -Name "testo" -ItemType "directory"
Restore-Temps $myitems

and as for now where I'm testing this I have errors comming up like this one.

Copy-Item : "Drive not found. A Drive with the name "@{name=Device.txt; originpath=C" is not found.
In T:\00Scripts\OTC-Copy\OTC-BCK-Complex(Theorie).ps1:8 character:13
+             Copy-Item -Path "$item.Temppath\$item.name" -Destination  ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{name=Device.txt; originpath=C:String) [Copy-Item], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.CopyItemCommand

Edit 4:

For any reason, I don't know why, it gets fixed if I do it like this.

foreach($item in $myitems){
    $x = $item.originpath
    $y = $item.name
    Copy-Item -Path "$x\$y" -Destination $item.Temppath -PassThru
}
1
  • 2
    The simplest way to store an output object from a foreach is just assign a variable to the foreach loop. You can do so like $var = foreach ($something in $somethingelse) { $obj }. Commented Aug 19, 2019 at 14:59

2 Answers 2

1

The canonical way of doing what you described is this:

function Get-Something {
    $data = @(foreach (...) {
        # ...
        # do stuff
        # ...
        # then create custom objects with the desired information
        New-Object -Type PSObject -Property @{
            'Itemname'   = ...
            'Originpath' = ...
            'Temppath'   = ...
        }
    })
    return ,$data
}

or this (slightly simplified, since PowerShell functions automatically return all non-captured output):

function Get-Something {
    ,@(foreach (...) {
        # ...
        # do stuff
        # ...
        # then create custom objects with the desired information
        New-Object -Type PSObject -Property @{
            'Itemname'   = ...
            'Originpath' = ...
            'Temppath'   = ...
        }
    })
}

Appending to an array in a loop should be avoided for performance reasons, because with every iteration the array would be re-created with the size increased by one, then all existing elements would be copied, and finally the new element would be placed in the additional field.

The array subexpression operator around the foreach loop ensures that $data contains an array, regardless of how many elements the loop produces.

The comma in the return statement prevents PowerShell from unrolling the array upon returning it to the caller. More specifically, it wraps the array $data into a second array, so that PowerShell unrolls only that outer array, leaving the inner array untouched.

Sign up to request clarification or add additional context in comments.

4 Comments

I get the way of doing so. But copy-item doesn't have an ouput as it looks or am I missing something since I dont get any data out of my function
@Kevin Just output whatever you need inside the loop. If Copy-Item doesn't produce the output you need you have to create it yourself.
This is my stucking point at the moment. Maybe I'm trying to hard to get the "perfect output" like Itemname Originpath Temppath. I'm kind of confused from my own thougths but thank you for the help
@Kevin Build custom objects with the desired information: [PSCustomObject]@{'Itemname'=...; 'Originpath'=...; ...}.
1

Maybe this will help. Passthru the copies to the $temp to a variable, then you can use that variable to reverse it. Copy-Item can take an array as the source.

$items2copy = Echo file1 file2
$temp = 'temp'
$originpath = '.'
Mkdir temp
Echo hi | Set-Content file1,file2

$pathremind = Copy-Item $items2copy $temp -PassThru # backup

Copy-Item $pathremind $originpath                   # restore

Umm, if you had a csv like this:

item,originpath,temp
file1,.,temp
file2,.,temp

backup would be:

$a = import-csv backups.csv
$a | foreach { $item,$originpath,$temp = $_.item,$_.originpath,$_.temp 
cp $originpath/$item $temp } 

restore would be:

$a = import-csv backups.csv
$a | foreach { $item,$originpath,$temp = $_.item,$_.originpath,$_.temp
cp $temp/$item $originpath } 

3 Comments

Does this not copy everything to any place ? If there are diffrent paths this won't work or am I wrong here ?
That's true. It doesn't remember multiple originpath's. I didn't get that from your question.
no problem it wasn't clear from my side. But still thank you for the input, still learned something from it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.