I was trying to write a simple script to ping a list of computers, and output the result in a table. I ended up doing this, which works fine:
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * | select -expand name | % {
$output = New-Object PSObject
$output | Add-Member NoteProperty "Computer name"($_)
$output | Add-Member NoteProperty "Ping result"("$($(Test-Connection $_ -count 1 -quiet).ToString())")
write $output }
However, I'd like to understand why my first two attempts didn't work, so that I can avoid making the same mistakes later. Here they are:
Script 1: See edit below
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * |
select -expand name | % { $computer = $_; $obj = "" |
select #{Name="Computer";Expression="$computer"},`
#{Name="Pingable";Expression="$($(Test-Connection $computer -count 1 -quiet).ToString())"}
$obj }
Output 1:
Computer Pingable
-----— -----—
Note: Under the table headers, this script actually prints one blank line for each computer I'm pinging.
Script 2:
$table = #{Expression={$_};Label="Computer"},#{Expression={"$($(Test-Connection $_ -count 1 -quiet).ToString())"};Label="Pingable"}
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * | select -expand name | format-table $table
Output 2:
mickeymouse
goofy
minnie
pluto
frank
This one doesn't even output a table...it just prints one computer name per line.
I'd appreciate if someone could explain what's going wrong in these two attempts. Thanks!
Edit: Got Script 1 to work.
Get-ADComputer -searchbase "OU=Materials,OU=MMC Computers,OU=REI,DC=REIDOMAIN,DC=LOCAL" -filter * |
select #{Name="Computer";Expression={$_.Name}},#{Name="Pingable";Expression={"$($(Test-Connection $_.Name -count 1 -quiet).ToString())"}};
Still curious about Script 2
In your second example, you are using the -ExpandProperty of Select-Object which effectively strips the data from the object and outputs an array of strings which format-table then outputs as a list.
See this example:
#First create the array of objects
$rawData = #( #{"Name"="First Obj"; "OtherParam"=1;}, #{"Name"="Second Obj"; "OtherParam"=2;})
$objects = $rawData | %{new-object -type psobject -prop $_}
#Just output the objects
$objects | format-table
Output:
Name OtherParam
---- ----------
First Obj 1
Second Obj 2
Now select the name property, this gives an array of objects with just a single property "name"
$objects | select name | format-table
Output:
Name
----
First Obj
Second Obj
Expand the name property, this gives an array of strings that format table just lists with no heading:
$objects | select -expand name | format-table
Output:
First Obj
Second Obj
Related
I am trying to write a powershell script to check all of the online computers and then make it one neat column Here is the code I have so far...
$computers = get-adcomputer -LDAPFilter "(Name=SDA000*)" | Select-Object -Property Name
$computers1 = get-adcomputer -LDAPFilter "(Name=SDA005*)" | Select-Object -Property Name
$computers2 = get-adcomputer -LDAPFilter "(Name=SDA006*)" | Select-Object -Property Name
$computers3 = get-adcomputer -LDAPFilter "(Name=SDA007*)" | Select-Object -Property Name
$computers4 = ($computers) + ($computers1) + ($computers2) + ($computers3)
[array]$online = #($computers4.Name | % {test-connection -erroraction silentlycontinue -Count 1 $_})
$wIw = $online | Select-Object Address
$wIw
But the output always leaves the top 3 lines with extraneous data I don't want. i.e
Address
-------
SDA0003
SDA0007
SDA000B
SDA000C
SDA0050
SDA0051
SDA0054
SDA0057
SDA005F
SDA0061
SDA006B
SDA006D
SDA0076
I can write it to a text file and then pipe it to select-object -skip 3, but that does not seem to work with a variable.
thanks for any advice.
What you are seeing is the header (e.g. the "Address" property). To output it to the screen without the header, you can use the -HideTableHeaders in a Format-Table command:
...
$wIw = $online | Select-Object Address
$wIw | Format-Table -HideTableHeaders
Ohh yes, that treat is sometimes quit helpful but most of the time it is in the way. Here is how I get rid of it:
$computers = (get-adcomputer -LDAPFilter "(Name=SDA000*)" | Select-Object -Property Name).name
Looks like what you want can be done easier like this:
$wIw = (Get-ADComputer -LDAPFilter "(Name=SDA00*)" |
Where-Object { ($_.Name | Test-Connection -Count 1 -Quiet -ErrorAction SilentlyContinue) }).Name
I am querying SCCM database to check the history of users who logged into a computer.
What I have so far works fine however there is a lot of data and I would like to group them all together. For example here is the output for one computer:
These are all logons of the same user (let's say JohnDoe123).
What I want is, instead of having like 30 entries for John, 20 entries for Jane, etc. I want a total of each user. For example:
Computer1 - JohnDoe123 - FullName - Latest time for LastConsoleUse - 500 (total number of console logons) - Latest TimeStamp - 50 000 (total minutes)
You see what I mean?
Obviously I can't sum up the LastConsoleUse and TimeStamp values, so ideally I would like to have just the latest value.
I'm trying ... | Group-Object -property SystemConsoleUser but it's returning an hashtable which isn't the format I'm after:
I'm pretty confused when it comes to manipulating objects within an object like this, so thanks for your help!
#Hist Users SCCM
$ConnexionsUsagers = $null
$poste = "X"
$SiteCode = "X"
$SiteServer = "X"
$ResourceID_Name = (Get-WmiObject -namespace root\sms\site_$SiteCode -computer $SiteServer -query "select ResourceId,Name from SMS_R_SYSTEM where SMS_R_SYSTEM.Name LIKE '%$poste%'")
$ConnexionsUsagers += foreach ($item in $ResourceID_Name) {
$query = #"
SELECT *
FROM SMS_GH_System_SYSTEM_CONSOLE_USER
WHERE SMS_GH_System_SYSTEM_CONSOLE_USER.ResourceID
LIKE '%$($item.ResourceId)%'
"#
Get-WmiObject -Namespace root\sms\site_$SiteCode -Computer $SiteServer -Query $query |
Where-Object {$_.SystemConsoleUser -ne $null} |
Select-Object #{name='Poste';expression={$item.Name}}, SystemConsoleUser,
#{name='Nom complet';expression={Get-ADUser -Properties userprincipalname ($_.SystemConsoleUser -replace "X\\") | Select-Object -ExpandProperty userPrincipalName}},
#{name='LastConsoleUse';expression={[DateTime]::ParseExact(($_.LastConsoleUse).Split('.')[0], "yyyyMMddHHmmss", [System.Globalization.CultureInfo]::InvariantCulture)}},
NumberofConsoleLogons,
#{name='TimeStamp';expression={[DateTime]::ParseExact(($_.TimeStamp).Split('.')[0], "yyyyMMddHHmmss", [System.Globalization.CultureInfo]::InvariantCulture)}},
TotalUserConsoleMinutes
}
$ConnexionsUsagers |
Sort-Object #{expression="Poste"; Ascending=$true}, #{expression="TimeStamp"; Descending=$true} |
Out-GridView
You can achieve the desired result using Group-Object and Measure-Object.
$ConnexionsUsagers | Group-Object -Property SystemConsoleUser |
Select-Object #{n='SystemConsoleUser';e={$_.Name}},
#{n='Poste';e={($_.group | Group-Object -Property Poste -NoElement).Name -join ';'}},
#{n='Nom Complet';e={($_.group | Group-Object -Property "Nom Complet" -NoElement).Name}},
#{n='NumberOfConsoleLogons';e={($_.group.NumberOfConsoleLogons | Measure-Object -Sum).Sum}},
#{n='TotalUserConsoleMinutes';e={($_.group.TotalUserConsoleMinutes | Measure-Object -Sum).Sum}},
#{n='LastConsoleUse';e={$_.group.LastConsoleUse | Sort-Object -Descending | Select-Object -First 1}}
Group-Object -Property PropertyName groups the array of objects by PropertyName. Every unique value of PropertyName will be grouped into a single line or item in the resulting collection. PropertyName values will now be listed under the Name property with all other properties and their values being listed as an array of objects under the Group property. You can then access the Group property to access the remaining ungrouped properties and values. The -NoElement switch leaves off the Group property. It is simply a way to minimize the returned data when it is not needed.
-join operator is used just in case there are multiple computers used by the user. -join ';' joins an array of values into a single string delimited by the semi-colon.
Help me with some problem. I am new in PS and
i need output data to table view.
Looks like this.
name1 name2
----- -----
value1 value2
But i have:
$a=(get-service).name
$b=(get-service).Status
foreach ($name in $a)
{
$data = [pscustomobject]#{name1 = $name}
}
$data
RESULT
name1
-----
XboxNetApiSvc
WITHOUT FOREATCH
$a=(get-service).name
$b=(get-service).Status
$data = [pscustomobject]#{name1 = $a ; name2 = $b }
$data
Result
name1 name2
----- -----
{2GISUpdateService, AcronisActiveProtectionService, AcrSch2Svc, AdobeARMservice...} {Stopped, Running, Running, Running...}
All of that i need for this script
$list = ((Get-ADComputer -SearchBase "OU=PC,DC=cbu,DC=lan" -Filter {Enabled -eq "True" } -Properties DNSHostName).DNSHostName)
$encoding = [System.Text.Encoding]::UTF8
$up = #()
$down = #()
$table= #()
foreach ($pc in $list)
{
if ((Test-Connection -Count 1 -computer $pc -quiet) -eq $True)
{
$up += $pc
#write-host $pc "is up"
}
else
{
$down += $pc
#Write-Host $pc "down"
}
}
After all i need output values of $up and $down in 2 columns
You probably have a custom commandlet but you can run something similar to:
(Get-Service) | select Name,Status | Format-Table
UPDATE
After reading your update. At the end of your script you have two arrays $up and $down. I will declare it the static way to make an example easier
$up = #('pc1', 'pc2')
$down = #('pc3','pc4', 'pc5')
Because arrays can be diffrent length you need to calculate maximum length with:
$max = ($up, $down | Measure-Object -Maximum -Property Count).Maximum
And than create an object which "merges" above arrays with:
0..$max | Select-Object #{n="Up";e={$up[$_]}}, #{n="Down";e={$down[$_]}}
The output is:
Up Down
-- ----
pc1 pc3
pc2 pc4
pc5
If you are using Get-Service as example only then, you can just use Select :
Get-Service | Select Name, Status
Else
$MyList | Select Name1, Name2
Moreover, if you have a complex command and you want to extract a table of PSObject :
Get-Process | Select-Object -Property ProcessName, Id, WS
Read more about Select-Object : https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/select-object?view=powershell-4.0
Yes Piotr Stapp is rights. You can use Format-Table
Example 1:
Get-Process | Sort-Object starttime | Format-Table -View starttime
Example 2:
(Get-Service) | select Name,Status | Format-Table
Example 3:
Get-Process | FT
I have a script that reads from a list of computers, does a test connection. If it gets a reply from the Test-Connection, it does a if/else and builds a variable from a Get-ChildItem that reads from the suspect system C:\Users to see the last person to log in and select the name and last write time of the last user that logged in, and does a Write-Host of the results. If the Test-Conneciton didn't get a reply, it builds a variable of the system name with a "offline" statement and does a Write-Host to show it. Then, to finish it all off, it exports the results to a CSV.
Several things I am having issues with:
The variable for the Get-ChildItem does a Select-Object Name, LastWriteTime and builds the results into a variable. I would like to display those results (and of course export them into the CSV) separately instead of combined.
I need to trim the results or modify the script so it doesn't include extra characters in the results.
Here is an example of the results from the Get-ChildItem when the Test-Connection gets a reply from the machine (of course system name, IP address and user name have been changed to protect the innocent):
SYSTEMNAME #{IPV4Address=192.168.0.1} #{Name=John.Doe; LastWriteTime=03/08/2017 08:11:48}
The name and last write time are combined in the results and I need to split them out in the display and the CSV export as well as trim the extra characters. Something like this, where systemname, IP address, name and lastwritetime would all appear in their own cells in the CSV:
SYSTEMNAME 192.168.0.1 Name=John.Doe LastWriteTime=03/08/2017 08:11:48
Code below:
$computerList = Get-Content "D:\filelocation\LastLogIn.txt"
foreach ($Computername in $computerList) {
$ipreachable = Test-Connection $computerName -EA SilentlyContinue -Count 1 |
select IPV4address
$output =#()
if ($ipreachable) {
$LastUserLoggedIn = Get-ChildItem "\\$computername\c$\Users" -EA SilentlyContinue |
Sort-Object LastWriteTime -Descending |
Select-Object Name, LastWriteTime -First 1
$Details = "$LastUserLoggedIn"
Write-Host $computername $ipreachable $Details
} else {
$details = "$computerName Computer does not exisit or is offline"
Write-Host $Details
}
[PSCustomObject]#{
SystemName = $Computername
IPV4Address = $ipreachable
UserLogInDetails = $details
} | Export-Csv "D:\filelocation\lastuserreults.csv" -NoType -Append
}
Expand the IP address:
... | Select-Object -Expand IPV4Address | Select-Object -Expand IPAddressToString
and don't turn the directory information into a string:
$Details = "$LastUserLoggedIn"
Build your data object like this:
$obj = [PSCustomObject]#{
SystemName = $Computername
IPV4Address = $ipreachable
UserName = $LastUserLoggedIn.Name
Timestamp = $LastUserLoggedIn.LastWriteTime
}
So that you can display the information on the console as well as export it to a CSV:
$obj | Format-Table -AutoSize
$obj | Export-Csv 'C:\path\to\your.csv' -NoType -Append
I am trying to combine two variables each containing a list of values:
cls
$Sites = Get-ADReplicationSite -Filter *
$Subnets = Get-ADReplicationSubnet -Filter *
$a = New-Object PSObject
$a | add-member Noteproperty "Site" $Sites.Name
$a | add-member Noteproperty "Subnet" $Subnets.Name
$a | format-table
My output looks like this:
Site Subnet
---- ------
{Default-First-Site-Name, SITE1, SI... {10.0.0.0/24, 20.0.0.0/24, 30.0.0.0/...
As the above does not result in a clear table I wonder where I went wrong. Preferably I would combine these two variables into a .csv file. However I am not sure on how I would give each list a Header before piping it to the Export-CSV cmdlet.
Assuming that the number of sites is equal to the number of subnets, try this:
$sites | Foreach {$i=0}{new-object pscustomobject -prop #{Site=$_;Subnet=$subnets[$i]}; $i++} | Format-Table