Seeking Powershell Function to Check if multiple Folders Exist Before moving files

214 Views Asked by At

The Back Story: I back up my android apps before installing updates to a single folder on my NAS. I want to use a Windows machine that is mapped to this folder to run a powershell script daily if not weekly which I know how to do.

The Goal: Is to move the files by partial name (Ex: Adobe Acrobat * & Adobe Scan *) into a folder structure that is predefined using the company name and then inside that folder the product. (EX: \Adobe\Acrobat\ & \Adobe\Scan)

So far I have:

$Adobe = "Z:\APK\Adobe\" #Set Path For Adobe Folder


#Adobe Products
If (!(test-path $Adobe)) #Check if Adobe Folder Does Not Exist
{ 
    #If Does Not Exist Create Folder
    New-Item -ItemType Directory -Force -Path $Adobe 
}
#Move Anything matching "Adobe" in its name to the $Adobe folder
Move-Item Z:\Adobe* $Adobe -Force 

The Problem:

  1. As you can see in my code I am putting everything with Adobe* into the Adobe folder but can't figure out how to use whitespaces to grab the product name from the above examples.

  2. There has to be an easier way than writing a test path for each folder as there is over 100 apps and I would generally like to store more from family and friends so you can see how that will grow. So I would like to have a function do the work of checking all folders in a loop and if they do not exist have it create that structure. To make it easier we can use the above example of two Adobe products.

Disclaimer: If I ever release the code it will be on Github and open source with Credits built into my script but I intend to use this for personal use and 0 Commercial gain

2

There are 2 best solutions below

7
Abraham Zinala On

To get the ball rolling so others may comment as well, i'll kick it off. Hopefully I understood you right so bear with me. Say we have all these apps you're trying to move in location A. Assuming that the app names have a space seperated by product ( Adobe ), then version ( Acrobat ) we can take an approach of splitting the names, by product and version.

$Where_My_Apps_Are = "E:\My\Apps\Location"
$Where_I_want_Them_To_Be = "D:\My\Apps\Destination"

$My_Apps = Get-ChildItem -Path $Where_My_Apps_Are -Filter "Adobe*" -File -Recurse 
    foreach ($App in $My_Apps) {
        
        $Name_Split = $App.BaseName.Split(' ')
        $App_NameFolder = Join-Path -Path $Where_I_want_Them_To_Be -ChildPath $Name_Split[0]
        $App_Version    = Join-Path -Path $App_NameFolder -ChildPath $Name_Split[1]

        $App_Name_Test = Test-Path -Path $App_NameFolder
        $App_Version_Test = Test-Path -Path $App_Version
            if ($App_Name_Test -eq $false) {

                New-Item $App_NameFolder -ItemType Directory

                    if ($App_Version_Test -eq $false) {

                        New-Item $App_Version -ItemType Directory
                        Move-Item $App.FullName -Destination $App_Version

                    }
                    else {

                        Move-Item $App.FullName -Destination $App_Version

                }
            }
            elseif ($App_Version_Test -eq $false) {

                New-Item $App_Version_Test -ItemType Directory
                Move-Item $App.FullName -Destination $App_Version

            }
            else {

                Move-Item $App.FullName -Destination $App_Version

            }
    }

See, the problem with this, is i'm assuming all applications will be product, then version format seperated by a space. We can collect all related apps into a variable ( $My_Apps ), split the name, test against each section of the name, create a folder if not there, move the item into the directory, or just move the item (app) into the directory if directory is there.

Probably best if you turn this into a function and pass it a filter variable to search for specific apps just for the convenienve of manual movement, but you can also have it do it for all apps it finds; assuming they're all in the format mentioned above.

Please note: just wanted to point readers in the right direction ( if i understood this correctly ) so they can give you a better answer.

7
Daniel On

I might do something like this

$path = 'C:\temp\powershell\apk_organizer\apk'
$apkFiles = Get-ChildItem -Path $path -Filter *.apk -File

$apkFiles | ForEach-Object {
    # Get vendor and product strings
    $vendor, $product, $null = $_.BaseName -split ' '

    # Generate the new path
    $newPath = [System.IO.Path]::Combine($path, $vendor, $product) 
    # or 
    # $newPath = Join-Path $path (Join-Path $vendor $product)

    # Create new path if it does not exist
    if (!(Test-Path $newPath)){
        New-Item -ItemType Directory -Path $newPath | Out-Null
    }

    # Move file to new path (Remove -WhatIf after testing)
    Move-Item $_ -Destination $newPath -Verbose -WhatIf
}