Reputation: 1200
I am trying to set an alert if the REMAINING AVAILABLE space of my SQL mdf data FILE is less than 2000 MB. See below:
$SQLInstances = "A","B","C"
$SQLQuery = " USE DB
SELECT CONVERT(DECIMAL(10, 2), CAST(CAST(10240 - size/128.0 AS NVARCHAR(50)) + size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS INT)/128.0 AS NVARCHAR(50))) AS ActualSpaceAvailableMB
FROM sys.database_files
WHERE name = 'DB'"
$login = "XYZ"
$password = "123" | Convertto-SecureString -AsPlainText -Force
$creds = New-Object System.Management.Automation.Pscredential -Argumentlist $login,$password
$SMTPServer = "10.0.0.0.0.0" # This is your SMTP Server
$to = "ME@ME.COM"# This is the recipient smtp address 1
$from = "NOREPLY@YOU.COM" # This will be the sender´s address
foreach ($SQLInstance in $SQLInstances) {
$output = Invoke-Sqlcmd -ServerInstance $SQLInstance -Database DB -Query $SQLQuery |
Select-Object -ExpandProperty ActualSpaceAvailableMB #-QueryTimeout 1200 -Verbose -ErrorAction Stop 4>&1
if ($output -lt 2000 ) {
Send-MailMessage -SmtpServer $SMTPServer -Credential $creds -To $to -From $from -Subject " Alert at $SQLInstance" -Body "free space is $output MB. Please investigate!!"
} else {
Write-Output "Actual size is not less than 2 GB"
}
}
Now the problem sometimes the alert gives incorrect results i.e. even if the value in the $output
variable is greater than 2000 MB an email is still being send. I want it to send an email ONLY if the value in the $output
is less than 2000. Any ideas?
Upvotes: 1
Views: 3748
Reputation: 27606
You can do it the other way so $output gets cast to integer, instead of 2000 getting cast to string.
if ($output -and 2000 -ge $output) {
EDIT: added a null check
For example, this turns out to be true when they're both strings, which is not what you want.
'90' -gt 100
Upvotes: 0
Reputation: 200503
Comparisons in PowerShell have a tendency to yield unexpected results, because PowerShell tries to adjust the type of the second operand to match the type of the first operand. Thus if your first operand is a string the comparison will be a string comparison, not a numeric comparison.
Demonstration:
PS C:\> $s = '20' PS C:\> $s -gt 10 # ⇔ "20" -gt "10" True PS C:\> $s -gt 100 # ⇔ "20" -gt "100" True PS C:\> $s -gt 3 # ⇔ "20" -gt "3" False
To mitigate this cast the first operand to a numeric type:
PS C:\> [int]$s -gt 100 False PS C:\> [int]$s -gt 3 True
Upvotes: 7