Search code examples
powershellif-statementconditional-statementsmultiple-conditions

Powershell If statement with multiple conditions


I have a Powershell script with If statement and multiple conditions. My code is working great but I am looking for to display which condition my object doesn't respect.

Get-ChildItem $Path -Directory -Force | ForEach-Object {

$FolderName = $_.BaseName -match $Folderpattern
$DateOK = $_.LastWriteTime -lt (Get-Date).AddDays(-3))
$Folder = $_.BaseName
    
if (($FolderName) -and ($DateOK) {
                write-host("$Folder can be moved") 
            }
            else {
                write-host("$Folder can't be moved")
            }
        }

I would like to display "$folder can't be moved because it doesn't match the pattern" if it doesn't respect the $FolderName condition.

And display "$folder can't be moved because the last write time is less than 3 days" if it doesn't respect the $DateOK condition.

thanks for the help


Solution

  • There are various ways to go about this; but this one is clean and easy to understand, so would be my preferred route:

    
    Function Move-FolderConditional { # todo: give this cmdlet a better name for your context
        [CmdletBinding()]
        Param (
            [Parameter(Mandatory, ValueFromPipeline)]
            [System.IO.DirectoryInfo[]]$Path
            ,
            [Parameter(Mandatory)]
            [System.IO.DirectoryInfo]$Destination
            ,
            # files matching this pattern get moved to the target
            [Parameter(Mandatory)]
            [string]$ArchivableFolderPattern
            ,
            # Files older than this date get moved to the target
            [Parameter()]
            [string]$MinKeepDateUtc = (Get-Date).AddDays(-3).ToUniversalTime()
        )
        Process {
            foreach ($directory in $Path) {
                if ($directory.BaseName -notmatch $ArchivableFolderPattern) {
                    Write-Warning "Could not move folder '$($directory.FullName)' as the name does not match the required pattern"
                    continue;
                }
                if ($directory.LastWriteTimeUtc -ge $MinKeepDateUtc) {
                    Write-Warning "Could not archive folder '$($directory.FullName)' as it was last updated at '$($directory.LastWriteTimeUtc.ToString('u'))'"
                    continue;
                }
                try {
                    #Move-Item -Path $directory -Destination $Destination -ErrorAction Stop # Uncommend this if you actually want to move your files
                    Write-Information "Successfully moved '$($directory.FullName)' to '$($Destination.FullName)'" 
                } catch [System.Management.Automation.ItemNotFoundException] { # For this exception we'd probably check in the Begin block instead - but this is just to give the idea that we could add a try/catch if required
                    Write-Warning "Could not archive folder '$($directory.FullName)' the target directory does not exist: '$($Destination.FullName)'"
                }  
            }
        }
    }
    
    # Example usage
    Get-ChildItem $path -Directory -Force | Move-FolderConditional -ArchivableFolderPattern '^log' -InformationAction Continue -Destination 'z:\archive\'
    

    But other options are available (I've just included snippets to give the gist of these):

    Switch Statement

    switch ( $directory )
    {
        {$_.BaseName -notmatch $ArchivableFolderPattern}
        {
            Write-Warning "Could not move folder '$($_.FullName)' as the name does not match the required pattern"
            break
        }
        {$_.LastWriteTimeUtc -ge $MinKeepDateUtc}
        {
            Write-Warning "Could not archive folder '$($_.FullName)' as it was last updated at '$($_.LastWriteTimeUtc.ToString('u'))'"
            break
        }
        default 
        {
            Write-Information "Successfully moved '$($_.FullName)' to '$($Destination.FullName)'" 
        }
    }
    

    Flags

    [bool]$archiveFolder = $true
    if ($directory.BaseName -notmatch $ArchivableFolderPattern) {
        Write-Warning "Could not move folder '$($directory.FullName)' as the name does not match the required pattern"
        $archiveFolder = $false
    }
    if ($directory.LastWriteTimeUtc -ge $MinKeepDateUtc) { 
        # note: this will process even if archivefolder is already false... you can use `else` or amend the condition to include `$archiveFolder -or ($directory.LastWriteTimeUtc -ge $MinKeepDateUtc)`; though if going that route it's better to use the switch statement.
        Write-Warning "Could not archive folder '$($directory.FullName)' as it was last updated at '$($_.LastWriteTimeUtc.ToString('u'))'"
        $archiveFolder = $false
    }
    if ($archiveFolder) {
        Write-Information "Successfully moved '$($directory.FullName)' to '$($Destination.FullName)'" 
    }
    

    Other

    Or you can do combinations of the above (e.g. use the switch statement to set your flags (in which case you can optionally remove the break so that all issues are displayed).