How to replace a null or empty value in PowerShell? - powershell

I have a function pulling data from an appliance, here is the code:
$allSFD = get-sklqsessions -apil $userAdmin $passAdmin $applianceIP <- so far there is no issue here
now :
if ($allSFD)
{
<#$allSFD | select-object #{N='username'; E={$_.username}},
#{N='Client IP'; E={$_.publicip}}, | format-table -autosize
#>
### write files
$allSFD | export-Clixml -path "c:\users\temp\file1.xml"
}
else { write-warning "no users connected to the appliance"}
whenever there is a user connected to the system, but idle, the appliance will keep the users in the connected list but his/her ip will be empty no IP, so no data in client ip = publicip.
Then I want to add something like 0.0.0.0
Right now any idle user is getting exported to the xml just a user name no ip , the publicip is empty.
How can I achieve this?

You can put anything you like into a property expression, including control statements like if(){...}:
$allSFD |Select Username,#{N='Client IP'; E={if([string]::IsNullOrEmpty($_.publicip)){"0.0.0.0"}else{$_.publicip}}} |Export-CliXml ...
Single-line if/else statements might look a bit "messy", but as #mklement0 helpfully points out, in PowerShell 7+ we have a ternary statement that we can use instead:
$allSFD |Select Username,#{N='Client IP'; E={[string]::IsNullOrEmpty($_.publicip) ? "0.0.0.0" : $_.publicip }} |Export-CliXml ...
This makes it slightly more readable :)

Related

Powershell: Extract Exchange property and Display in array

I need to get all Exchange users into an Array, with a column for their SIP address and another column for all SMTP addresses (as seen in the EmailAddresses field).
So for now I am trying this against a single user and should that work out I can use "-ResultSize Unlimited" and do all. Although for now:
$list_UsersExtCloud =
Get-Recipient e12367 |
Select-Object Alias, EmailAddresses, #{Name = 'SIP'; Expression = { $_.EmailAddresses | Where-Object { $_ -like "*sip*" } -join ',' } }
I could extract the SIP by iterating using a FOR LOOP through each user properties with EmailAddresses | where {$_ -like "*sip*"}, but I'm trying to extract it in the EXPRESSION statement itself.
How can I get this to work?
You are on the right track, however you are trying to join the objects without referencing the sub-properties you are actually interested in. Try something like:
$list_UsersExtCloud =
Get-Recipient e12367 |
Select-Object Alias, EmailAddresses, #{ Name = 'SIP'; Expression = { ($_.EmailAddresses | Where-Object { $_.Prefix -eq "SIP" }).ProxyAddressString -join ',' } }
I changed the Where clause to use the Prefix. I grouped the address objects then unrolled the ProxyAddressString from them. This give good input to the -join. You can also do this with the AddressString property, I wasn't sure which you were really interested in.
Note: If you let this output without assigning to a variable the EmailAddresses property will likely bump the SIP property off the screen. I found that a little confusing while working this out, thought I'd mention it.
Warning: Get-Recipient has a known issue. When making very large queries it won't page properly and will return an LDAP cookie error. So this may blow up if you have enough recipients. An alternative is to query for mail enabled objects using Get-ADObject then customize the object similarly using Select-Object.

ADSI query, I am trying to find the flag for identifying if a local account is disabled

To try get all possible values I attempted to print them all out, I thought this was a simple approach to get the values I am interested in. However I am interested in identifying if an account is disabled or not and it seems to me that this value isn't available for local accounts? That seems crazy so I must be missing something. Any help would be appreciated.
I have checked here but that doesnt define the flag, ive tried the obvious (Disabled, Enabled) but as I say no luck and I cant see anything obvious from the results from below.
$user_adsi = [ADSI]"WinNT://$ComputerName"
$users = $user_adsi.Children | where { $_.SchemaClassName -eq 'user' } | select *
try
{
foreach ($user in $users)
{
Write-Host $user
}
}
You will need to check UserFlags property for the binary bit that represents decimal 2 for disabled users.
$disabledUsers = $user_adsi.Children |
where { $_.SchemaClassName -eq 'user' -and $_.UserFlags[0] -band 2}
Since the UserFlags (works like UserAccountControl) is type PropertyValueCollection, you will need to index into its first element [0].
You could also use Where() method to create two lists of disabled and enabled users:
$DisabledUsers,$EnabledUsers = $user_adsi.children.where({$_.SchemaClassName -eq 'user'}).where({$_.UserFlags[0] -band 2},'Split')
The Split mode will output items that met the condition into the first variable ($DisabledUsers) and output the remaining items in the second variable ($EnabledUsers).

Import list of IP addresses, resolve their hostnames, export IP and hostname to spreadsheet

Complete powershell noob here. I am attempting to do the following:
Import a list of IP addresses from a text file.
Obtain the hostname of each IP address. If unable to, provide the failure reason.
Export both IP address and hostname (or error) line by line in a CSV.
I was attempting to use the following script however I do not know what IP address is which since there are some errors:
get-content .\dnsip.txt | ForEach-Object {([system.net.dns]::GetHostByAddress($_)).hostname
Can someone help me write a script that would do this?
Thanks!
You can do the following:
Get-Content .\dnsip.txt | ForEach-Object {
$obj = "" | Select-Object IPAddress,Hostname
try {
$obj.Hostname = ([system.net.dns]::GetHostByAddress($_)).hostname
} catch {
$obj.Hostname = 'Unknown Host'
}
$obj.IPAddress = $_
$obj
} | Export-Csv -Path Output.csv -NoType
Explanation:
During each iteration, a new object $obj is created with two properties, IPAddress and Hostname, set as empty strings. A try {} block is used to attempt to retrieve the Hostname value using your method. If it succeeds, Hostname will be assigned the value returned by the command. If that throws an exception, it will be caught by the catch {} block. In side catch {}, the Hostname property is given a value of Unknown Host. Then IPAddress is assigned the current item processed ($_) from your Get-Content.
All custom objects are exported to Output.csv via Export-Csv. The -NoType switch prevents data type information from being printed at the top of the CSV file.

Iterate thru SubjectOrBodyContainsWords of an Exchange transport rule

I want to create a PowerShell script to extract a text file with a list of words specified in an Exchange Server 2016 transport rule. I'm stuck with handling the obtained list.
To get the list, I do this within Exchange Management Shell:
$SubjectOrBodyContainsWords = Get-TransportRule "My rule name" | Select-Object -Property SubjectOrBodyContainsWords
I verify that the list is correct using this:
$FormatEnumerationLimit = 10000
$SubjectOrBodyContainsWords | Format-Table -HideTableHeaders | Out-String -width 10000
The output looks like (Just an example, actual list is much much bigger):
{unsubscribe, mailing, blabla}
Now I want to iterate the list to do something with each item. I tried something like this (Just a simple example):
$I = 10;
foreach ($A in $SubjectOrBodyContainsWords)
{
$I++;
$I;
$A;
}
The problem is that it doesn't loop all the items. It looks like there is only one item.
What am I doing wrong?
Thanks.
I don't have access to my Exchange server at the moment but just try the following suggestions. Just ask for and expand the property.
(Get-TransportRule "My rule name").SubjectOrBodyContainsWords
# Or
Get-TransportRule "My rule name" |
Select-Object -ExpandProperty SubjectOrBodyContainsWords
Since this returns an array, you need to expand that listing.
Or you can do this to turn into a list to work with...
"{unsubscribe, mailing, blabla}" -replace '\s|{|}' -split ',' | foreach {
# Code to do something with each item
$PSItem }
# Results
unsubscribe
mailing
blabla
... and
Potential duplicate of this use case
Exchange Shell - SubjectOrBodyContainsWords

Removing PowerCLI list truncation

I have the following snippet
Get-VM | select name, #{ Name = "IP Addresses"; Expression = { $_.Guest.IPAddress }} | Format-List
This outputs a fantastic list of servers and IP addresses however i notice some iPV6 addresses are truncated.
Name : eg.example.com
IP Addresses : {192.168.100.18, 2a03:2658:1068:0:250:56ff:feaf:593f, fe80::2504:56ff:feaf:593f, 192.168.100.1...}
How can I expand this to output all address space? I have tried using -ExpandProperty but this seems to fail.
Join the elements of the list to a string:
... | select name, #{n='IP Addresses';e={$_.Guest.IPAddress -join ', '}} | ...
The data is there but PowerShell has truncated it on screen by only showing you the first 4 elements in the IP Addresses property array. If you want to leave the property as an array you could change the preference variable for $FormatEnumerationLimit. By default it is 4.
$FormatEnumerationLimit = -1
That will force it to display the entire array on screen. It would be a good idea to save the value before you change it in case you need to reverse.
$savedValue = $FormatEnumerationLimit