$PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 22621 4391
Consider the following snippet
# Function to determine if the OS is Windows Server
function Is-WindowsServer {
$osVersion = (Get-WmiObject -Class Win32_OperatingSystem).Caption
return $osVersion -like "*Server*"
}
# Function to check if SMB/Network Sharing is installed
function Is-SMBInstalled {
if (Is-WindowsServer) {
Write-Output "Detected Windows Server. This should print."
$smbFeature = Get-WindowsFeature -Name FS-SMB1 -ErrorAction SilentlyContinue
if ($smbFeature -and $smbFeature.Installed) {
return $true
} else {
return $false
}
} else {
Write-Output "Detected Windows 10/11 client. This should print."
$smbFeature = Get-WindowsOptionalFeature -Online -FeatureName "SMB1Protocol" -ErrorAction SilentlyContinue
if ($smbFeature -and $smbFeature.State -eq "Enabled") {
return $true
} else {
return $false
}
}
Write-Output "This should be unreachable."
}
Is-SMBInstalled # probe
if (Is-SMBInstalled -eq $true) {
Write-Output "If above line is False. This should not print."
}
Expected output on Windows 10/11 with Samba disabled:
Detected Windows 10/11 client. This should print.
False
Script output on Windows 10/11 with Samba disabled:
Detected Windows 10/11 client.
False
If above line is False. This should not print.
Moreover, by itself,
if (Is-SMBInstalled -eq $true) {
Write-Output "If above line is False. This should not print."
}
doesn't seem to properly calls Is-SMBInstalled. Without Is-SMBInstalled # probe
, the output is just If above line is False. This should not print.
I've tried refactoring by putting Is-SMBInstalled inside a $variable, this works in a sense that the function is properly called. But the conditional still behaves unexpectedly.
I also tried the grouping function as per https://stackoverflow.com/a/66585435/14097947 if ((Is-SMBInstalled)) {
, this also doesn't work.
By using Write-Output
the result of Is-SMBInstalled
is always a mixed-content array because Write-Output
push its contents to the Success Stream(aka stdOut) the same as Return
.
And thus is always true when compared left-side.
Replace the Write-Output
with Write-Host
, which does not write on the Success Stream.
And since you are already there:
Wim
cmdlets has been obsolete since Powershell 3, and have been removed from powershell 6+: replace Get-WimObject
with Get-CimInstance
.have a example
# Function to determine if the OS is Windows Server
function Test-IsWindowsServer {
# Left-side Filtering for the win.
# It returns $False if it finds nothing, and $True if it finds anything.
# NOTE WELL: I don't have Windows Server available to test now, so check if
# the filter is working correctly.
[bool](Get-CimInstance -ClassName Win32_OperatingSystem -Filter 'Caption Like "%server%"')
}
# Function to check if SMB/Network Sharing is installed
function Test-IsSMBInstalled {
if (Test-IsWindowsServer) {
Write-Host 'Detected Windows Server. This should print.'
$smbFeature = Get-WindowsFeature -Name FS-SMB1 -ErrorAction SilentlyContinue
# no reason for a IF, this will return either $true or $False directly.
return ($smbFeature.Installed)
}
# Strictly speaking you don't need the Else because it's not reaching here
# if Test-IsWindowsServer is $true, evaluate yourself if it's clearer with
# or without.
else {
Write-Host 'Detected Windows 10/11 client. This should print.'
$smbFeature = Get-WindowsOptionalFeature -Online -FeatureName 'SMB1Protocol' -ErrorAction SilentlyContinue
# no reason for a IF, this will return either $true or $False directly.
# Evaluate using "-like" instead of "-eq".
return ($smbFeature.State -eq 'Enabled')
}
# A Write-Warning is the perfect fit for this.
Write-Warning 'This should be unreachable.'
}
# This will print the 'Detected' version line and then the boolean output.
Test-IsSMBInstalled
# note this will print again the 'Detected' version line.
if (Test-IsSMBInstalled) {
Write-Host 'If above line is False. This should not print.'
}