I'm working on a quick string of code that allows me to search a specific print server and also its contents such as printers. What I want for it to do is once getting the printer information to be able to find a specific printer using the port name which in this case is an IP address not quite sure if is possible but I haven't found a command that lets me define a search using those values.
Get-Printer -computerName "server01"|select-object -Property Name, PortName
Name PortName
Printer01 X.XX.XXX.X
Prnter02 X.XX.XX.XX
is there a way to be able to find a printer using the Get-Printer commandlet and utilizing the port name to find the specific printer?
I'm just explaining in more detail #JeffZeitlin very correct answer.
Get-Printer - The Get-Printer cmdlet retrieves a list of printers installed on a computer. You can also use Get-Printer to retrieve the properties of a single printer, and then use that information as input into other cmdlets.
Get-Printer | Get-Member - The Get-Member cmdlet gets the members, the properties and methods, of objects.
Get-Printer | get-member
Get-Printer | Select-Object - The Select-Object cmdlet selects specified properties of an object or set of objects. It can also select unique objects, a specified number of objects, or objects in a specified position in an array.
Get-Printer | select-object -Property Name, PortName
Get-Printer | Select-Object | Where-Object - The Where-Object cmdlet selects objects that have particular property values from the collection of objects that are passed to it. For example, you can use the Where-Object cmdlet to select files that were created after a certain date, events with a particular ID, or computers that use a particular version of Windows.
Get-Printer | select-object -Property Name, PortName | where PortName -eq "PORTPROMPT:"
Get-Printer -ComputerName
Get-Printer -ComputerName $env:Computername | select-object -Property Name, PortName | where PortName -eq "PORTPROMPT:"
Scripting Example Get-Printer
$server = "$env:Computername"
$printersportnames = Get-Printer -ComputerName $server | select-object -ExpandProperty PortName
#Write-Host $printersportnames
$results = New-Object System.Collections.ArrayList # Empty Array
ForEach ($printerportname in $printersportnames) {
$printerportname = $printerportname.ToString()
#Write-Host $printerportname
$output = Get-Printer -ComputerName $server | where-object {$_.PortName -eq $printerportname}
$x = $output.Name
$y = $output.PortName
$z = $output.CommunicationStatus
$a = $output.OperatingStatus
$Object = New-Object PSObject
$Object | Add-Member -Name 'Name' -MemberType Noteproperty -Value $x
$Object | Add-Member -Name 'PortName' -MemberType Noteproperty -Value $y
$Object | Add-Member -Name 'CommStatus' -MemberType Noteproperty -Value $z
$Object | Add-Member -Name 'OperStatus' -MemberType Noteproperty -Value $a
$results += $object
}
$results
Related
when attempting to run my script then I got the following output. So Computer Name is duplicating.
I am getting {192.168.1.11, 192.168.1.12, $null} in DNS.
Script :
$Result=Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'" -Property DNSServerSearchOrder,DNSHostname
$output = new-object PSObject
$output | add-member NoteProperty "ComputerName" $Result.DNSHostname
$output | add-member NoteProperty "DNSServerSearchOrder" $Result.DNSServerSearchOrder
$output
Output :
ComputerName DNSServerSearchOrder
------------ --------------------
{srv01, srv01} {192.168.1.11, 192.168.1.12, $null}
Use Select-Object when piping multiple results, like:
$Result | Select-Object -Property DNSHostname,DNSServerSearchOrder
DNSHostName DNSServerSearchOrder
----------- --------------------
srv01 {192.168.1.11, 192.168.1.12}
srv01 {$null}
The reason there are two results is you have two enabled adapters. The second has no DNS servers set
Get-NetTCPConnection | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State,#{name='NameofApp';expression={(Get-Process -id $_.OwningProcess).MainModule.FileVersionInfo.FileDescription}} | Format-Table -AutoSize
The above one works perfectly, Here I want to include the Username as well:
I know that Get-Process -IncludeUserName will return the UserName but I don't know how to join this in the above working command.
Using your current query, here is a simple modified approach that will solve your problem:
Get-NetTCPConnection | ForEach-Object {
$process = Get-Process -Id $_.OwningProcess -IncludeUserName
$description = $process.MainModule.FileVersionInfo.FileDescription
$username = $process.UserName
$properties = $_ | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State
$properties | Add-Member -Name "NameOfApp" -Type NoteProperty -Value $description
$properties | Add-Member -Name "UserName" -Type NoteProperty -Value $username
$properties
} | Format-Table -AutoSize
Explanation:
Pipe Get-NetTCPConnection through to Foreach-Object.
Get the process object with Get-Process, making sure to include User Names with the -IncludeUserName switch.
Store the descriptions and usernames in separate variables. Not necessary, but I split them up for clarity.
Get all the TCP connection properties that can be selected immediately with Select-Object into a System.Management.Automation.PSCustomObject. This uses the default pipeline variable $_ from Foreach-Object, which is basically the current item from GetNetTCPConnection. You can run Get-Help -Name about_Automatic_Variables to find out more about pipeline variables, and Get-Help -Name about_pipelines for finding out more about pipelines. Unfortunately, these Help files don't contain online versions.
Add the NameOfApp and UserName members to the object with Add-Member.
Format into a table with Format-Table and auto size columns with the -AutoSize switch.
You could also use regular foreach enumeration as well:
& {
foreach ($connection in Get-NetTCPConnection) {
$process = Get-Process -Id $connection.OwningProcess -IncludeUserName
$description = $process.MainModule.FileVersionInfo.FileDescription
$username = $process.UserName
$properties = $connection | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State
$properties | Add-Member -Name "NameOfApp" -Type NoteProperty -Value $description
$properties | Add-Member -Name "UserName" -Type NoteProperty -Value $username
$properties
}
} | Format-Table -AutoSize
The above is wrapping the foreach loop inside a script block, so you need to use the call operator & to run it. You can read more About Operators and About Script Blocks.
I can't copy the data from the grid window when using CTRL+C. It just closes the window.
My code:
Get-ADUser -Filter * | ForEach-Object -Process {
Add-Member -InputObject $_ -Name TerminalServicesProfilePath -Force -Membertype NoteProperty -Value (([ADSI]"LDAP://$($_.DistinguishedName)").TerminalServicesProfilePath) -PassThru
} | Select-Object -Property SamAccountName, TerminalServicesProfilePath | Out-GridView
This may or may not solve your problem, but instead of using Add-Member (which is of limited use in this case), try using a calculated property in your pipeline:
Get-ADUser -Filter * | Select-Object -Property #(
'SamAccountName'
#{
Label = 'TerminalServicesProfilePath'
Expression = { ([adsi]"LDAP://$($_.DistinguishedName)").TerminalServicesProfilePath }
}
) | Out-GridView
If you're using this in a script, or something of that nature, then your problem is not using the Wait switch on Out-GridView. See the documentation here.
Could someone provide a PowerShell script to join two function results based on common key columns.
Example:
Result1 and Result2 has common field 'Name'. I want to join both the results and fetch the below informations.
$Result1 = get-wmiobject -ComputerName localhost -Class win32_service
$Result2 = get-service
Result
Name : wuauserv
DisplayName : Windows Update
Status : Running
StartMode : Manual
ProcessId : 400
Use below PowerShell script to join both the results based on common key column (Name).
$Result1=get-wmiobject -ComputerName localhost -Class win32_service
$Result2=get-service
$Result=#()
for($i=0;$i -lt $Result2.count;$i++)
{
$startmode=($Result1 | where{$_.Name -eq $Result2[$i].Name})|Select StartMode,ProcessId
$tempObj=new-object PSObject
$tempObj | Add-member noteproperty Name $Result2[$i].Name
$tempObj | Add-member noteproperty DisplayName $Result2[$i].DisplayName
$tempObj | Add-member noteproperty Status $Result2[$i].Status
$tempObj | Add-member noteproperty StartMode $startmode.StartMode
$tempObj | Add-member noteproperty ProcessId $startmode.ProcessId
$Result += $tempObj
}
$Result
No need to combine the output of the two commands. All of the properties are already out from the Get-WMIObject. (Personally I like using the CIM cmdlets instead of WMI wherever possible too)
Get-CimInstance Win32_Service | select Name, DisplayName, State, StartMode, ProcessId
Edit: The output of State from gcim is the Status property of Get-Service (Here's a calculated property to fix that, if that's an issue)
Get-CimInstance Win32_Service | select Name, DisplayName, #{Name="Status";Expression={$_.State}}, StartMode, ProcessId
try this
$result=get-wmiobject -ComputerName localhost -Class win32_service | %{ New-Object psobject -Property #{ objectwmi=$_; objectgetservice=(get-service | where name -eq $_.Name | select -first 1)} }
I'm working on a basic PowerShell script that inputs a pair of dates then gets all accounts with passwords expiring between those times. I'd like to output the data to the console in a way that is compatible with Export-Csv. That way the person running the script can either just view in the console, or get a file.
Here is my script:
[CmdletBinding()]
param(
[string]$StartDate = $(throw "Enter beginning date as MM/DD/YY"),
[string]$EndDate = $(throw "Enter end date as MM/DD/YY")
)
$start = Get-Date($StartDate)
$end = Get-Date($EndDate)
$low = $start.AddDays(-150)
$high = $end.AddDays(-150)
$passusers = Get-ADUser -Filter { PasswordLastSet -gt $low -and PasswordLastSet -lt $high -and userAccountControl -ne '66048' -and userAccountControl -ne '66080' -and enabled -eq $true} -Properties PasswordLastSet,GivenName,DisplayName,mail,LastLogon | Sort-Object -Property DisplayName
$accts = #()
foreach($user in $passusers) {
$passLastSet = [string]$user.PasswordLastSet
$Expiration = (Get-Date($passLastSet)).addDays(150)
$obj = New-Object System.Object
$obj | Add-Member -MemberType NoteProperty -Name Name -Value $user.DisplayName
$obj | Add-Member -MemberType NoteProperty -Name Email -Value $user.mail
$obj | Add-Member -MemberType NoteProperty -Name Expiration -Value $expiration
$accts += $obj
}
Write-Output ($accts | Format-Table | Out-String)
This prints to the console perfectly:
Name Email Expiration
---- ----- ----------
Victor Demon demonv#nsula.edu 1/3/2016 7:16:18 AM
However when called with | Export-Csv it doesn't:
#TYPE System.String
Length
5388
I've tried multiple variations using objects, and data tables, however it seems like I can only get it to work for console or for CSV, not for both.
Replace
Write-Output ($accts | Format-Table | Out-String)
with
$accts
That way your users can run your script any way they like, e.g.
.\your_script.ps1 | Format-Table
.\your_script.ps1 | Format-List
.\your_script.ps1 | Export-Csv
.\your_script.ps1 | Out-GridView
...
Format-Table | Out-String converts your output to a single string whereas Export-Csv expects a list of objects as input (the object properties then become the columns of the CSV). If Export-Csv is fed a string, the only property is Length, so you get a CSV with one column and one record.
$accts | ConvertTo-Csv | Tee -File output.csv | ConvertFrom-Csv