Ouput of script shows extra comma - powershell

I have a script where the script check NIC binding order.
$result = Invoke-Command -ComputerName $ComputerName -ScriptBlock {
function Get-BindOrder {
$Binding = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage").Bind
$Return = New-Object PSobject
$BindingOrder = #()
foreach ($Bind in $Binding) {
$DeviceId = $Bind.Split("\")[2]
$Adapter = (Get-WmiObject Win32_Networkadapter | Where {$_.GUID -eq $DeviceId }).NetConnectionId
$BindingOrder += $Adapter
}
$BindingOrder
} #EndFunction
CLS
Get-BindOrder
}
$adapteresult = $result -join (",")
when I echo this $adapteresult = $result, I am getting an output as below
PS C:\> $adapteresult
vEthernet (10.211.14.0_20)
storage
Ethernet 5
Ethernet 4
Ethernet 2
Ethernet 6
The same variable when I added $adapteresult = $result -join (","), I am getting out put with extra command in between.
vEthernet (10.241.24.0_21),storage,Ethernet 5,,Ethernet 4,Ethernet 2,Ethernet 6,,
I do not want any extra comma in output. Expecting output like below:
vEthernet (10.241.24.0_21),storage,Ethernet 5,Ethernet 4,Ethernet 2,Ethernet 6,

(Get-WmiObject Win32_Networkadapter | Where {$_.GUID -eq $guid}).NetConnectionId appears to be returning $nulls that you are capturing in $BindingOrder. Displayed on the screen they take up no space but they are there regardless. Running a condensed version of your code locally on my machine ...
$results = ((Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage").Bind | Foreach-Object {
$guid = $_.split("\")[2]
(Get-WmiObject Win32_Networkadapter | Where {$_.GUID -eq $guid}).NetConnectionId
})
Using that lets look at $results:
$results
$results.Count
$results -contains $null
Local Area Connection
6
True
On my machine I only have one match for Local Area Connection. However the $results have stored 6 items at least one of which is a $null. You need to filter out these results it seems in your query.
$Adapter = (Get-WmiObject Win32_Networkadapter | Where {$_.GUID -eq $DeviceId }).NetConnectionId
if($Adapter){
$BindingOrder += $Adapter
}
Should do it. if $adapter is null or empty string then it won't be added to $bindingorder

I have corrected myself and its working fine now
$a = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage").Bind | ForEach-Object {
$guid = ($_ -split '\\')[2]
Get-WmiObject -Query "SELECT * FROM Win32_NetworkAdapter WHERE GUID='$guid'" |
Select-Object -ExpandProperty NetConnectionID
}
$b = $a -join","

Related

Error handling with Get-wmiObject for pscustomobject in Powershell

Building this script I want to have the output stored in a TXT file and leave the details blank which cannot be found.
It works for the Get-ADuser function but not for Get-wmiObject.
I've got my PC names and user ids from a CSV file but sometimes a user doesn't have a PC or the workstation is not turned on so I get no output. Then I want to leave those details blank.
I've tried with try and catch but it seems not working. Any advice?
$userName1 = "UserX"
$Computernames = Import-CSV 'C:\PCnames.csv' -Delimiter ';'
$pcName = $Computernames.Where({ $_."User ID" -match $userName1})."PC Name"
$aProperties = #(
'Name'
'mail'
'OfficePhone'
'Description'
'PasswordLastSet'
'LastBadPasswordAttempt'
'LockedOut'
'Enabled'
'msDS-UserPasswordExpiryTimeComputed'
)
$aUser = Get-Aduser -Identity $userName1 -Properties $aProperties
$aUser
$IP = try {Get-WmiObject Win32_NetworkAdapterConfiguration -Computername $pcName -ea stop |
Where { $_.IPAddress } |
Select -Expand IPAddress |
Where { $_ -like '10.33*' -or $_ -like '10.44*'} }
catch {""}
$Model = try { (Get-WmiObject -Class Win32_ComputerSystem -ComputerName $pcName -ea stop ).Model}
catch {""}
$OS =try { Get-WmiObject win32_operatingsystem -Computername $pcName -ea stop | select csname, #{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}}
catch{""}
[pscustomobject]#{ UserID = $aUser.Name
Mail = $aUser.mail
Phone = $aUser.OfficePhone
Hostname = $pcName
LockedStatus = $aUser.LockedOut
AccountEnabled = $aUser.Enabled
LastBadPasswordAttempt = $aUser.LastBadPasswordAttempt
OSVersion = $OSVersion.Version
OSName = $OSVersion.Name
IPAddress = $IP
Model = $Model }

PowerShell not running all lines in Function

Below Function is not running the lines "If ($script:AADServersTable)" down... I have put a write-host and that is working, however the variables are not working below that
Function get-AADVariables
{
$script:AADServersTable = New-Object 'System.Collections.Generic.List[System.Object]'
$scriptBlockaadinstalled = {
Get-WmiObject -Class Win32_Product |
where name -eq "Microsoft Azure AD Connect synchronization services" | select Name, Version}
##$scriptBlockaadinstalled = {hostname}
Import-Module ActiveDirectory
$servers = Get-ADComputer -Filter 'operatingsystem -like "*server*" -and enabled -eq "true"' | Select-Object -Property Name -ExcludeProperty Release
## just a single invoke-command
foreach ($server in $servers) {
$aadinstalledresults = Invoke-Command -ComputerName $server.name -ScriptBlock $scriptBlockaadinstalled ##-HideComputerName
$aadinstalledresults = $aadinstalledresults.PSComputerName
$script:AADServersTable.Add($aadinstalledresults)
}
If ($script:AADServersTable) {
Write-Host 'working'
$AADServers = ($script:AADServersTable | Group-Object -NoElement).Name | Get-Unique
$AADServers = $AADServers -split "`n"
$AADServer = $AADServers[0]
$StandByAADServer = $AADServers[1]
$SecondStandByAADServer = $AADServers[2]
}
}

System.String[] - Result

I did a search and I understand the issue that some of these are arrays. What I am not sure I understand is why I am getting this when I am specifically trying to return just one value.
I am using a ForEach loop and pulling from a text file the names of the computers I want to query.
I want to verify that the IP address I am pinging is the same computer I want to connect to. We have many users on VPN and the DNS doesn't update fast enough. This means we get some incorrect information.
$NIC2 = Get-WmiObject win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.DNSDomain -eq "usms.contoso.com"} | Select-Object IPAddress
This should give me only one IP address and not an array, but unfortunately I get the System.String[] in the CSV output. If I just type this command out in the PowerShell command line it works beautifully, but not when I put it into a CSV.
any ideas?
Thanks in advance.
Entire code below - I get the results for everything except the $NIC2 and doing $NIC2.IPAddress[0] doesn't seem to work.
Putting $NIC2[0] just give me this in that column
dapterConfiguration -ComputerName $computer | Where-Object {$_.DNSDomain -eq "contoso.com"} | Select-Object IPAddress
#Definitions of variables
#************************
#Defines the location and name of the text file from where computers will be pulled
$Computers = Get-Content "c:\Temp\computers.txt"
#Defines the variable and format for Date
$Date = Get-date -UFormat %h_%d_%y_%H%M
#Define the name of the files to output
$OutputFile = "C:\Temp\Verify-Computer-$Date.csv" #All Computers On-Line Status will be provided in this file
#Defines the Array where to put the data and the $Ping variable to store the IP address
$DataArray = #()
$Resolution = New-Object System.Object.NetworkInformation.Ping
#Define A Function that will test which computers are on-line and create files to use in the other function.
ForEach ($computer in $Computers)
{
#Defining the variables
$TESTConnection = $null
$Object = $null
$Value = $null
$IPAddress = $null
$NameResolution = $null
$PingAddress = $null
$NIC = $null
$NIC2 = $null
$NICIP = $null
# Ping computer
$TESTConnection = Test-NetConnection -ComputerName $computer | Select-Object PingSucceeded
#If connection is live Get IP address
IF ($TESTConnection.PingSucceeded -eq "True") {
$IPAddress = Test-NetConnection -ComputerName $computer -InformationLevel "Detailed" | Select-Object RemoteAddress
$NIC = Get-WmiObject win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.DNSDomain -eq "contoso.com"} | Select-Object MACAddress, DNSHostName
$NIC2 = {Get-WmiObject win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.DNSDomain -eq "contoso.com"} | Select-Object IPAddress}
$Value = $TESTConnection.PingSucceeded
$PingAddress = $IPAddress.RemoteAddress
}
Else {
$Value = $TESTConnection.PingSucceeded
$PingAddress = $IPAddress.RemoteAddress
$NICIP = "NOT REACHABLE"
}
# Create object
$Object = New-Object PSObject -Property ([ordered]#{
Computer_Target = $computer
ONLINE = $Value
IPAddress_PING = $PingAddress
IPResolved = $NIC2.IPAddress
NameResolved = $NIC.DNSHostName
MACAddress = $NIC.MACAddress
})
# Add object to array
$DataArray += $Object
#Display object
}
If($DataArray)
{
#Output Array Data into a CSV File
$DataArray | Export-Csv -Path $OutputFile -NoTypeInformation
}
#end of file
OK - I finally figured it out because I kept going around in circles and getting nowhere.
Thank you to Zett42 who led me in the right direction but I was still failing.
My first problem was that I hadn't identified $NIC2 as an Array which was part of my issue when trying $NIC2[0]. However, even after being Defined as an Array it still didn't work.
I then created another array and did this $NICIP = $NIC2.IPAddress and then output $NICIP[0] which works. Not exactly sure why that works.
Here is the entire code
#Definitions of variables
#************************
#Defines the location and name of the text file from where computers will be pulled
$Computers = Get-Content "c:\Temp\computers.txt"
#Defines the variable and format for Date
$Date = Get-date -UFormat %h_%d_%y_%H%M
#Define the name of the files to output
$OutputFile = "C:\Temp\Verify-Computer-$Date.csv" #All Computers On-Line Status will be provided in this file
#Defines the Array where to put the data and the $Ping variable to store the IP address
$DataArray = #()
$Resolution = New-Object System.Object.NetworkInformation.Ping
#Define A Function that will test which computers are on-line and create files to use in the other function.
ForEach ($computer in $Computers)
{
#Defining the variables
$TESTConnection = $null
$Object = $null
$Value = $null
$IPAddress = $null
$NameResolution = $null
$PingAddress = $null
$NIC = $null
$NIC2 = #()
$NICIP = #()
# Ping computer
$TESTConnection = Test-NetConnection -ComputerName $computer | Select-Object PingSucceeded
#If connection is live Get IP address
IF ($TESTConnection.PingSucceeded -eq "True") {
$IPAddress = Test-NetConnection -ComputerName $computer -InformationLevel "Detailed" | Select-Object RemoteAddress
$NIC = Get-WmiObject win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.DNSDomain -eq "contoso.com"} | Select-Object MACAddress, DNSHostName
$NIC2 = Get-WmiObject win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.DNSDomain -eq "contoso.com"} | Select-Object IPAddress
$Value = $TESTConnection.PingSucceeded
$PingAddress = $IPAddress.RemoteAddress
$NICIP = $NIC2.IPAddress
}
Else {
$Value = $TESTConnection.PingSucceeded
$PingAddress = "NOT REACHABLE"
}
# Create object
$Object = New-Object PSObject -Property ([ordered]#{
Computer_Target = $computer
ONLINE = $Value
IPAddress_PING = $PingAddress
IPResolved1 = $NICIP[0]
NameResolved = $NIC.DNSHostName
MACAddress = $NIC.MACAddress
})
# Add object to array
$DataArray += $Object
#Display object
}
If($DataArray)
{
#Output Array Data into a CSV File
$DataArray | Export-Csv -Path $OutputFile -NoTypeInformation
}
#end of file

Get Hostname and MAC address from all PCs in AD

I'm trying to get the hostname and the MAC address from all PCs in the Active Directory. I know that MAC addresses are not in the Activce Directory. That's why I already used a small script from someone else. The point is that I have to make a list of hostnames, which I can do, but then the other script runs into a problem because some computers are not online.
Can anyone help me get a list with only the pc's that are online?
This is the part that searches the list I create with hostnames.
$Computers = Import-CSV C:\Users\admin_stagiair\Desktop\Computers.txt
$result = #()
foreach ($c in $Computers){
$nic = Invoke-Command {
Get-WmiObject Win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"'
} -ComputerName $c.Name
$x = New-Object System.Object | select ComputerName, MAC
$x.Computername = $c.Name
$x.Mac = $Nic.MACAddress
$result += $x
}
$result | Export-Csv C:\Users\admin_stagiair\Desktop\Computers.csv -Delimiter ";" -NoTypeInformation
And this is the part that I tried to make search the list and filter out the online computers, which absolutely does not work and I can't figure out how to do it.
$Computers = Import-Csv C:\Users\admin_stagiair\Desktop\Computers.txt
foreach ($c in $Computers) {
$ping = Test-Connection -Quiet -Count 1
if ($ping) {
$c >> (Import-Csv -Delimiter "C:\Users\admin_stagiair\Desktop\online.txt")
} else {
"Offline"
}
}
Last bit, this is the part I use to create a list of all computers in the Active Directory.
Get-ADComputer -Filter {enabled -eq $true} -Properties * |
select Name > C:\Users\(user)\Desktop\Computers.txt
If you only want one property from Get-ADComputer don't fetch all
a computer could have more than one MAC, to avoid an array be returned join them.
$result += inefficiently rebuilds the array each time, use a PSCustomObject instead.
Try this (untested):
EDIT: first test connection, get MAC only when online
## Q:\Test\2018\09\18\SO_52381514.ps1
$Computers = (Get-ADComputer -Filter {enabled -eq $true} -Property Name).Name
$result = ForEach ($Computer in $Computers){
If (Test-Connection -Quiet -Count 1 -Computer $Computer){
[PSCustomPbject]#{
ComputerName = $Computer
MAC = (Invoke-Command {
(Get-WmiObject Win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').MACAddress -Join ', '
} -ComputerName $Computer)
Online = $True
DateTime = [DateTime]::Now
}
} Else {
[PSCustomPbject]#{
ComputerName = $Computer
MAC = ''
Online = $False
DateTime = [DateTime]::Now
}
}
}
$result | Export-Csv C:\Users\admin_stagiair\Desktop\Computers.csv -Delimiter ";" -NoTypeInformation
What about trying something like this:
# Get all computers in list that are online
$Computers = Import-Csv C:\Users\admin_stagiair\Desktop\Computers.txt |
Select-Object -ExpandProperty Name |
Where-Object {Test-Connection -ComputerName $_ -Count 1 -Quiet}
# Grab the ComputerName and MACAddress
$result = Get-WmiObject -ComputerName $computers -Class Win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"' |
Select-Object -Property PSComputerName, MacAddress
$result | Export-Csv C:\Users\admin_stagiair\Desktop\Computers.csv -Delimiter ";" -NoTypeInformation

PSCustomObject foreach

I've created a custom object and I'm having some trouble with the output of one array.
$i = "computername"
$adsi = [ADSI]"WinNT://$i"
$Object = $adsi.Children | ? {$_.SchemaClassName -eq 'user'} | % {
New-Object -TypeName PSCustomObject -Property #{
ComputerName = $i.toupper() -join ''
UserName = $_.Name -join ''
Groups = ($_.Groups() |Foreach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}) -join ','
Disabled = Get-WmiObject -ComputerName $i -Class Win32_UserAccount -Filter "LocalAccount='$true'"|Select-Object -expandproperty Disabled
}
}
$object
The problem is with the Disabled array, instead of showing one item per line I'm getting
{False, True, False, False} I know I have to probably add at % somewhere on that line but I'm not sure where.
Anyone have any advice?
What you're seeing makes sense to me - you're creating an array of objects holding ComputerName, UserName, etc. and in Disabled you're getting an array of values because you're querying all local user accounts and getting their disabled status. I suspect what you want is to determine each user in turn is disabled. In which case, you need to extend the Filter on Get-WMIObject a bit to only get a single user.
$i = "computername"
$adsi = [ADSI]"WinNT://$i"
$Object = $adsi.Children | ? {$_.SchemaClassName -eq 'user'} | % {
$UserName = $_.Name -join '';
New-Object -TypeName PSCustomObject -Property #{
ComputerName = $i.toupper() -join ''
UserName = $UserName
Groups = ($_.Groups() |Foreach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}) -join ','
Disabled = Get-WmiObject -ComputerName $i -Class Win32_UserAccount -Filter "LocalAccount='$true' and name='$UserName'"|Select-Object -expandproperty Disabled
}
}
$object