Home > database >  Powershell - Skip folder if it doesn't exist
Powershell - Skip folder if it doesn't exist

Time:01-27

I would like to run a PowerShell script by right-clicking a .PS1 file -> Run with PowerShell. The issue is that the $srcRoot includes three different parent directories, which one, some, or none may exist of 'C:\parentfolder5.5\web\','C:\parentfolder7.0\web\', and/or 'C:\parentfolder8.0\web\'. However, running the script directly in a PowerShell terminal seems to work for the parent folders that do exist even though there are errors that pop up for the parent folders that do not exist.

The goal would be to continue running the script based on the parent directories that do exist, which currently it looks like the .PS1 file stops after looking at the first item in the $srcRoot list. Below is the code being worked on:

$filterLists = '*overview*', '*summary*', '*home*', '*floor*', '*flr*', '*level*', '*lvl*', '*roof*', '*basement*', '*first*', '*second*', '*third*', '*fourth*'

$srcRoot = 'C:\parentfolder5.5\web\','C:\parentfolder7.0\web\','C:\parentfolder8.0\web\'
$dstRoot = $MyInvocation.MyCommand.Path
    
$params = @{
    Path      = LiteralPath      = $srcRoot |Where-Object { Test-Path -LiteralPath $_ -PathType Container }
    Filter    = 'views'
    Recurse   = $true
    Directory = $true
}

# All folders under `$srcRoot` with name 'views'
$viewsFolders = Get-ChildItem @params #this line is where the issue 
seems to start when Right-clicking -> Run with PowerShell
$params.LiteralPath = $viewsFolders.FullName
$params.Filter = 'graphics'
# All folders under `$viewsFolders` with name 'graphics'
$graphicsFolders = Get-ChildItem @params
$params.Remove('Directory')
$params.LiteralPath = $graphicsFolders.FullName
$params.File = $true # Only search for Files
$params.Force = $true
$params.Remove('Filter')

# All files under `$graphicsFolders`
foreach($file in Get-ChildItem @params)
{
    # Where the file name contains one of these filters
    foreach($filter in $filterLists)
    {
        if($file.Name -like $filter)
        {
            #$file
            Copy-Item -Path $($file.FullName) -Destination $dstRoot
            # if you want to stop at the first finding
            # add `break` here
        }
    }
}

Help on this would be greatly appreciated!

CodePudding user response:

You can use Where-Object to filter the list of paths. Use Test-Path to test whether each exists and is a directory path:

$params = @{
    LiteralPath = $srcRoot |Where-Object { Test-Path -LiteralPath $_ -PathType Container }
    Filter      = 'views'
    Recurse     = $true
    Directory   = $true
}

# this will only attempt directory paths that actually exist now
$viewsFolders = Get-ChildItem @params

Note: Use of LiteralPath (instead of Path) above is intentional - using Path will cause PowerShell to attempt to expand wildcards like ?, * or [abc], whereas -LiteralPath only take exact file/folder names.

  •  Tags:  
  • Related