PowerShell中Ahsay备份脚本的备份类型识别搜索异常求助
Let's break down why your current logic is misbehaving and fix it step by step.
The Root Cause
Your variable $LogType isn't a single string—it's an array of strings, where each element is a line from your log file (thanks to Get-Content returning lines as separate array items).
PowerShell's comparison operators like -like and -notlike work differently on arrays than they do on single strings:
$LogType -notlike "*Database*"returns all lines that don't contain "Database". Since most of your log lines don't have that keyword, this expression evaluates to$truein a boolean context (because it's a non-empty array).$LogType -like "*file list*"returns the lines that do contain "file list"—which exists in your log, so this also evaluates to$true.
When you combine these with -and, both conditions are true, so your if branch runs even though the log contains "Database"—exactly the behavior you're trying to avoid.
Fixes to Get the Logic Right
You need to check whether the entire log content meets your criteria, not individual lines. Here are two clean approaches:
Option 1: Convert the Log Array to a Single String
First, join all log lines into one string, then check for the presence/absence of your keywords against the whole text:
get-childitem -Exclude *Scheduler*, *SystemTray*, *Archived*,*System* | select -last 1 | Get-Content -totalcount 13 -outvariable LogType # Combine array into a single string with line breaks preserved $fullLog = $LogType -join "`n" # Now check the entire log content if ($fullLog -notlike "*Database*" -and $fullLog -like "*file list*") { # Your file-only backup handling logic here }
You can also use -match instead of -like if you prefer regex (e.g., $fullLog -notmatch "Database"), which works the same way for simple substring checks.
Option 2: Check for Existence of Keywords in the Array
If you want to avoid string concatenation, you can explicitly check whether any line contains each keyword:
get-childitem -Exclude *Scheduler*, *SystemTray*, *Archived*,*System* | select -last 1 | Get-Content -totalcount 13 -outvariable LogType # Check if any line contains "Database" or "file list" $containsDatabase = $LogType | Where-Object { $_ -like "*Database*" } | Select-Object -First 1 $containsFileList = $LogType | Where-Object { $_ -like "*file list*" } | Select-Object -First 1 # Only run the branch if NO Database lines exist AND File List lines do exist if (-not $containsDatabase -and $containsFileList) { # Your file-only backup handling logic here }
This is efficient because it stops searching as soon as it finds the first matching line (thanks to Select-Object -First 1).
Quick Note on Case Sensitivity
If your logs might have variations in capitalization (e.g., "File List" instead of "file list"), you can adjust the checks:
- For
-like, PowerShell is case-insensitive by default—add the-CaseSensitiveflag only if you need exact case matching. - For
-match, use the(?i)regex modifier:$fullLog -match "(?i)file list"
Testing this with your sample log: since there's a line containing "Database", $containsDatabase will have a value, so -not $containsDatabase becomes $false, and the if branch won't run—exactly what you need.
内容的提问来源于stack exchange,提问作者Tom Halverson

