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
CodePudding user response:
If this is just for checking and not for keeping a log where you need those specific messages I might go for something simple where we just capture the true and false values for each of the tests.
$path = C:\temp
Get-ChildItem $Path -Directory -Force |
ForEach-Object {
[PSCustomObject]@{
Folder = $_.BaseName
LastWriteTime = $_.LastWriteTime
FolderNameTest = $_.BaseName -match 'test'
DateOKTest = $_.LastWriteTime -lt (Get-Date).AddDays(-30)
}
}
Sample Output
Folder LastWriteTime FolderNameTest DateOKTest
------ ------------- -------------- ----------
.git 06.09.2021 01:06:06 False True
.vscode 25.09.2021 10:06:11 False True
1 22.09.2021 22:30:26 False True
batch_test 02.05.2022 22:29:25 True False
cleanup 20.09.2021 10:02:51 False True
DeviceDatabase 26.09.2021 12:07:26 False True
host 22.09.2021 23:23:38 False True
move_logs 26.04.2022 19:28:59 False False
test_run 01.03.2022 22:14:14 True True
You can then pipe this to Export-Csv
if you like
CodePudding user response:
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).