包含多个条件的Powershell If语句



我有一个带有If语句和多个条件的Powershell脚本。我的代码工作得很好,但我正在寻找显示我的对象不尊重的条件。

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")
}
}

我想显示"$文件夹不能移动,因为它不匹配模式"如果它不符合$FolderName条件

并显示"$folder cannot be move because last write time少于3 days";如果它不符合$DateOK条件

thanks for the help

如果这只是为了检查,而不是为了在需要这些特定消息的地方保存日志,我可能会做一些简单的事情,我们只捕获每个测试的true和false值。

$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)
}
}

的示例输出
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

如果你愿意,你可以将它管道到Export-Csv

有多种方法;但这一个是干净的,容易理解的,所以将是我的首选路线:


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'

但是还有其他选项可用(我只是包含了一些片段来给出这些要点):

Switch语句

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)'" 
}
}

旗帜
[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)'" 
}
其他

或者您可以将上述操作组合起来(例如,使用switch语句设置您的标志(在这种情况下,您可以选择删除break,以便显示所有问题)。

最新更新