Removing PowerCLI list truncation - powershell

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

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.

How to replace a null or empty value in 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 :)

Add a column of data to query

I require an additional column added to this output called "Location" with each row of data containing the word "Varonis".
$fs | ForEach-Object {
$machine = $_.ServerName
$_.Volumes | Select-Object #{n='machine';e={$machine}}, Share, FileWalkMethod
} | Export-Csv D:\data\splunk\otl_varonis\otl_varonis_monitoring.csv -NoType
Current output:
"hmanas01n","E$","VaronisWindows"
Desired output:
"hmanas01n","E$","VaronisWindows", "Varonis"
Essentially this is a question of how to add custom fields to an existing object (i.e. data)...
In the code example you give, the columns of output are defined by the following command:
Select-Object #{n='machine';e={$machine}}, Share, FileWalkMethod
This effectively filters the data to just the Share and FileWalkMethod properties, as well as adding a new column called machine. The machine column is defined with two key-value pairs: n (or name/label) is the column title and e (or expression) is a bit of code that sets the value for that column; in this case whatever the $machine variable is set to.
You need to replicate the same mechanism that adds the machine column by adding this to the end of the Select-Object statement, where the expression is just a static value:
#{n="Location";e={"Varonis"}}

Print (2) columns from powershell array

I created this array with:
$arecords = Get-DnsServerResourceRecord -ZoneName "mydomain.local" -RRType "A"
If I do $arecords.HostName I get a list of the hostnames. If I do $arecords.RecordData I get a list of the IP's. How can print both columns AWK style? Like $arecords.Hostname.RecordData?
The A records are CIM objects, and the default output formatting provided with the DnsServer module must know how to format them, but converting them to string just gets you the DnsServerResourceRecordA text.
You need to get the .RecordData.IPv4Address property out, with a calculated property, e.g.
$arecords| Select-Object -Property hostname, #{name='IP'; Expression={ $_.RecordData.IPv4Address }}
aka
$arecords| select hostname, #{n='IP';E={$_.RecordData.IPv4Address}}

Parse string in Powershell

Learning powershell, trying to find out how to parse the first value from this resultset (10.60.50.40):
IPAddresses
-----------
{10.60.50.40, fe80::5ddf:a8f4:e29c:b66}
Normally I would just look it up, however, I don't know if {x, x} is a standard datatype of sorts in Powershell land.
Do I have to do rough string parsing, or is there some standard command to extract the first one, such as:
... | Select-Object IPAddresses | Select-String [0]
(I just made the select string part up. I'm lost.)
This is most likely the result of of the IPAddresses property of your object containing an array. The output you're seeing is stylized for display purposes, so it's not a string you would have to parse. Assuming your object is $obj, you should be able to do either of these:
$obj.IPAddresses[0]
$obj.IPAddresses | Select-Object -First 1
One solution is to use split function to convert the string into array and work with that like in the next steps:
Split the string into an array using the split function (comma is the item delimiter).
Grab the first item of the array (or whatever needed) and then also sanitize it (remove unnecessary curly bracket).
Example below:
$str = "{10.60.50.40, fe80::5ddf:a8f4:e29c:b66}"
$strArr = $str.Split(",")
Write-Host $strArr[0].Replace("{", "")
This is what I ended up doing:
$str = ... | Select-Object IPAddresses | ForEach {$_.IpAddresses}
Write-Host $str[0]
Depending on the source of your IPAddresses, this might not be optimal. You might get multiple IPAddresses per devices.
You might want to combine both approaches:
$str = ... | Select-Object -ExpandProperty IPAddresses | Select-Object -First 1
This will return the First IP address in your list per device.