PowerShell script - distinguish between 3 command outcomes - powershell

Can anyone tell me why I'm always get the same output result?
$syslocal = Get-WmiObject -Class Win32_UserAccount -Filter "localaccount=true" |
where {$_.Disabled -eq $False}
if ($syslocal -eq "") {
Write-Host "Syslocal Enabled"
exit 0
} else {
Write-Host "No Syslocal"
exit 0
}
It just needs to see if a account syslocal exist and if it's enabled or not
with 3 outcomes:
write host: syslocal does not exist, exit 0
write host: syslocal exist, but is disabled, exit 0
write host: syslocal exist and is enabled, exit 1010
But all outcomes are the same.

If your Get-WmiObject | Where-Object statement finds a match the variable $syslocal will contain a list of WMI objects. If the statement doesn't find a match (i.e. no local accounts exist or all of them are disabled) the variable will be empty. Neither an empty value nor an array of objects equal the empty string, so your check will always evaluate to $false.
Also, for a 3-way check you need to actually check 3 ways.
Change your code to something like this and it should do what you expect.
$syslocal = Get-WmiObject -Class Win32_UserAccount -Filter 'localaccount=true'
if ($syslocal) {
if ($syslocal | Where-Object {-not $_.Disabled}) {
Write-Host 'Enabled local accounts exist.'
exit 1010
} else {
Write-Host 'Local accounts exist, but are disabled.'
}
} else {
Write-Host 'No local accounts.'
}
exit 0

this line is wrong:
if ($syslocal -eq "")
If it exist it's still not equal to ""
this should be:
if ($syslocal)
More details already explained on Ansgar Wiechers Answer...

Well there's this as well.
$syslocal = Get-WmiObject -Class win32_useraccount -filter "localaccount=true"
Foreach($account in $syslocal){
If ($syslocal) {
if($account.Disabled -eq $true) {
Write-Host "$($account.name) is currently Disabled"
} Else {
Write-Host "$($account.name) is currently Enabled"
}
} Else {
Write-host "Just no..."
}
}

Related

Basic multiple if statement logic flow syntax in PowerShell

I can't seem to understand how to continue to another IF statement. What I'm trying to do is:
IF Action 1 succeed then do X AND go to Action 2, else log it and RETURN to the next loop
If Action 2 succeed then do X AND go to Action 3, else log it and RETURN to the next loop
I am having issues with "AND go to Action 2" after action 1. I tried various ways but obviously the script below does not work. It can do Action 1 the test-connection, and if it succeeds will export the log else it will log a failure and RETURN to the next loop. HOWEVER, I cannot make it do the next action if successful.
$hostname = Import-Csv C:\Users\jackie.cheng\Desktop\TestComputers.csv
$hostname | % {
if (Test-Connection $_.hostname -count 1)
{Write-Host "$($_.hostname) Test-Connection Succeeded"
$array += [pscustomobject]#{
Name = $currentobject.hostname
Status = "Test-Connection Success"}
}
else {Write-Host "$($_.hostname) Test-Connection Failed"
$array2 += [pscustomobject]#{
Name = $currentobject.hostname
Status = "Failed Test-Connection"}
} return
if (Test-Connection $_.hostname -count 1)
{Write-Host "Second action ran"}
else {Write-Host "Second action failed"} return
}
Within the script block of a Foreach-Object, which is the full name of the command with the alias %, you can in fact use return to skip any statements after the return, and continue on to the next loop.
In your case you simply need to move your return into your else blocks like this:
If (Success Condition){
Actions to do on success
}
else{
Actions to do on fail
return
}
If (Success Condition 2){
...
}
else{
...
return
}
As mentioned in the comments to your question, be sure to read up on how return works in PowerShell as it is somewhat unusual and behaves differently in different contexts.
I would do it this way, just output the objects for either case. Notice the indenting to help see the structure of the code. Return is usually not needed. -ea 0 means "-erroraction silentlycontinue".
Import-Csv TestComputers.csv |
% {
if (Test-Connection $_.hostname -count 1 -ea 0) {
[pscustomobject]#{
Name = $_.hostname
Status = $true}
}
else {
[pscustomobject]#{
Name = $_.hostname
Status = $false}
}
}
Name Status
---- ------
yahoo.com True
microsoft.com False

Store the output of command ran on remote system and list in proper format and select the option from that list in powershell?

I am running the below command in one of my powershell function to get the list of services from remote computer
Get-WmiObject -Class Win32_Service -filter "name like '$envlist%'" -Impersonation 3 -Credential abcdomain\PXXXX -ComputerName $server | Format-List -Property Name
The above command gives me the below output and I want to store it in variable and list it in proper format
Name : ABC_xx02_TT_xcedf_1.0.00.0101
Name : ABC_xx02_TT_nghk_2.1.0.99999
Name : ABC_xx02_TT_nmk_3_1.0.3.7890
Name : ABC_xx02_TT_pnp_4.0.0.123
I am expecting the output in below way:(the below services could be more so need to use something like counter).Once I select any choice from below I want to store it in variable for e.g if I select "3" then it should store in variable $serivcename = ABC_LA02_TT_nmk_3_1.0.3.7890
1. Press 1 to select ABC_xx02_TT_xcedf_1.0.00.0101
2. Press 2 select ABC_xx02_TT_nghk_2.1.0.99999
3. Press 3 to select ABC_xx02_TT_nmk_3_1.0.3.7890
4. Press 4 to select ABC_xx02_TT_pnp_4.0.0.123
Please make a selection:
I have no idea of course what could be in '$envlist%', but apparently that gives you the result you need.
Right now, your code uses Format-List, but that does not display a usable console menu.
I would do it like this:
$collection = (Get-WmiObject -Class Win32_Service -Filter "name like '$envlist%'" -Impersonation 3 -Credential abcdomain\PXXXX -ComputerName $server).Name
while ($true) {
Clear-Host
for ($i = 1; $i -le $collection.Count; $i++) {
# build your menu
"{0}. Press {0} to select {1}" -f $i, $collection[$i - 1]
}
$answer = Read-Host "Please make a selection. Press Q to quit"
# test if the (string) answer is in range, or if the user wants to quit
# if so, break the while loop
if ($answer -match "[1-$($collection.Count)Q]") { break }
# when you reach this point, the user made an invalid choice
Write-Host "Invalid input, please try again" -ForegroundColor Red
Start-Sleep -Seconds 3
}
# do whatever you need with the selected option
if ($answer -ne 'Q') {
Write-Host "User selected '{0}'" -f $collection[[int]$answer - 1]
# DoStuff $collection[[int]$answer - 1]
}
Try this:
$i = 0
Get-WmiObject -Class Win32_Service -filter "name like '$envlist%'" -Impersonation 3 -Credential abcdomain\PXXXX -ComputerName $server | Foreach {
$i++
Write-host "$($i). Press $($i) to select $($_.name.split('=')[1])"
}
$input = read-host "Please make a selection"
Now selection will be stored in $input.

Powershell Switch Condition

I'm having a little trouble with a PS script right now.
What I am trying to do:
Depending on which OU a computer belongs to, it should get a different printer mapped.
I am trying this with a switch condition, but regardless of what I try the condition seems to be always TRUE (although I know it isn't)
When I type in the condition into PowerShell manually, I get the correct values if the condition is TRUE or FALSE. But as soon as I use it in the switch, the condition seems to be always TRUE.
What I have so far:
With dsquery I check if a computer belongs to a specific OU.
If a value is returned, which only happens if the query succeeds, I put it into my $SwitchDump variable (Condition TRUE).
From my understanding, if a device is not found in the OU, there is no value that will be passed to my $SwitchDump variable and hence should be $null right?
But it keeps mapping the printer.
Switch ($SwitchDump = dsquery computer $OU_TO_SEARCH_IN|findstr $env:COMPUTERNAME | Out-String)
{
$SwitchDump -ne $null {Add-Printer -ConnectionName \\$PrintServer\$DesiredPrinter}
}
Or am I just barking up the wrong tree?
Any ideas would be greatly appreciated.
$SwitchDump = dsquery computer $OU_TO_SEARCH_IN | findstr $env:COMPUTERNAME | Out-String
Switch ($SwitchDump)
{
{$_ -ne $null} {Add-Printer -ConnectionName \\$PrintServer\$DesiredPrinter}
}
You need to use $_ to represent the variable being tested by the Switch if you want to do anything beyond simple comparisons for values. You also need to make those comparisons a scriptblock by using { }.
You're assigning the dsquery to $SwitchDump... which will [almost] always return true ;-)
You probably want to perform an equality check i.e.
Switch ($SwitchDump -eq dsquery computer $OU...
Also it looks like you have your switch syntax slightly off: https://ss64.com/ps/switch.html
$SwitchDump = dsquery computer $OU_TO_SEARCH_IN|findstr $env:COMPUTERNAME
if (-not $SwitchDump) {
Write-Output "SwitchDump is empty"
}
switch ($SwitchDump) {
$null { Write-Host "SwitchDump = NULL" ; break; }
"value1" { Write-Host "SwitchDump = value1"; break; }
"value2" { Write-Host "SwitchDump = value2"; break; }
"value3" { Write-Host "SwitchDump = value3"; break; }
default { Write-Host "None of the above" ; break; }
}

powershell output multiple variables derived from processlist

I have the below bit of code, it is designed to simply ask for a Windows ProcessName, and then return a list of all instances of that process that are running.
$processName = Read-Host 'Please Enter the Process Name, as shown in Task Manager (not inc *32)'
if (!$processName)
{
"No Process Given"
}
else
{
"You Entered "+$processName
$filter = "name like '%"+$processName+"'"
$result = Get-WmiObject win32_process -Filter $filter | select CommandLine
$counter=1
foreach($process in $result )
{
write-host "$counter) $process"
$counter++
}
}
It works fine up until the point where it outputs the list.
If I do
echo $process
then I get what I am after e.g.
"C:\folder\AppName.exe"
"C:\folder\AppName.exe instance1"
If however I try to concatenate the $counter in front of it I get:
1) #{CommandLine="C:\folder\AppName.exe" }
2) #{CommandLine="C:\folder\AppName.exe instance1" }
I've tried write-host, write-output, echo, various combinations of "", +, but I can't get rid of the #{CommandLine= xxx } when I try to combine it with another variable
Is there a way to get what I am after? e.g.:
1) "C:\folder\AppName.exe"
2) "C:\folder\AppName.exe instance1"
try write-host "$counter) $($process.commandline)"
OR modify your selection :
$result = Get-WmiObject win32_process -Filter $filter | select -expandproperty CommandLine
explanation : without expandproperty you get a psobject with expandproperty you have a string

PowerShell - TRUE or FALSE returned If username exists in ActiveDirectory

I am wanting to check if an AD username exists, when I run the below condition I receive an error 'Get-ADUser : Cannot find and object with identity' This is obviously due to the specific username not existing, however if the condition is false then I want to echo a response to the user.
$username_value = "JSmith"
IF (Get-AdUser $username_value) {
Run script.....
}
ELSE {
Write-Host "The username does not exist."
}
EDIT: The answer below is correct for nearly every PowerShell cmdlet, but not Get-ADUser which somehow ignores -ErrorAction. I'll leave it here for future reference. In the meantime, you can use the following instead:
$user = Get-ADUser -filter {sAMAccountName -eq $username_value}
if (!$user) {
Write-Error "This username does not exist"
exit # or return, whatever is appropriate
}
You can just suppress the error using the -ErrorAction parameter. The return value from the cmdlet should be $null in that case and thus coerce nicely to $false.
$user = Get-ADUser -ErrorAction SilentlyContinue $username_value
if (!$user) {
Write-Error "This username does not exist"
exit # or return, whatever is appropriate
}
# run script ...