Finding the connectivity status of a printer by share name - powershell

I'm currently writing a test-page printing script, and am trying to work out if there is a way of "pinging" a printer when its only known details are share name (eg \SERVERNAME\PRINTER01).
Standard ping messages and test-connection tests don't perform this job as far as I can see. Any ideas of how to make this functionality in Powershell?

Assuming you are using a network printer and simply sharing it, try this:
$sharedPrinter = Get-CIMInstance CIM_Printer -ComputerName SERVERNAME |`
Where-Object{$_.ShareName -match 'PRINTER01'} |`
Select-Object -ExpandProperty PortName
Test-Connection $sharedPrinter

Related

Unable to use calculated properties with wmi

I'm trying to capture a few details regarding some processes on a windows server and as I understand it, performance counters are the way to go. Since the processes can be stopped/started at times, I wanted to make it a bit dynamic and give me the details of the running processes and with the commandline as well. Also, the process can have multiple instances running on the server with different command lines and process names. e.g. T-Process#1 , T-Process#2,T-Process#3.
Looking into WMI, I can't get everything from a single class and have to rely on two(Win32_Process and Win32_PerfFormattedData_PerfProc_Process). Since I can't use a single query to get details from two classes, I was going to use powershell and found a few posts about how to do so but I can't seem to make it work.
Get-CimInstance -Namespace root/cimv2 -Class Win32_process -Filter 'Name like "%T%"' -Property Name,Commandline,ProcessId | select-object Name,Commandline,ProcessId,#{Name='ProcessName';expression={(Get-CimInstance -CimSession (Get-CimSession | Where-Object ComputerName -eq $_.PSComputerName) -Namespace root/cimv2 -ClassName Win32_PerfFormattedData_PerfProc_Process -Filter 'IDProcess = $_.ProcessId' -Property Name).Name}}
I expected the code above to give me the process name(to be used in the performance counter), and the name, commandline and I do get everything but not the process name which is a calculated property.
Any help on this would be great. I've tried a few different iterations of the expressions and nothing seems to work.
Thanks,
Karan

PowerShell script to compile a csv file of all machines and last logged on users

I am in the process of writing a PowerShell script that should check every machine on my domain and export the last logged on user to a csv file. I seem to be getting multiple errors which I can not figure out why this is.
Get-WinEvent : There are no more endpoints available from the endpoint mapper
Get-WinEvent : The RPC server is unavailable So far I have wrote this:
$computers=get-adcomputer -filter {operatingsystem -like '*server*'}|select -exp Name
$data=ForEach($computer in $computers)
{
#Who-loggedinLast -computer $computer -maxresults 2
Get-WinEvent -Computer $computer -FilterHashtable #{Logname='Security';ID=4672} -MaxEvents 1|
select #{N='User';E={$_.Properties[1].Value}}
}
$data |export-csv c:\path.csv -notype ```
first, i think that because you running on WinEvent on each computer in computers, perhaps the first computer it checks isnt online, hence it cant reach the first one and fails.
second, like you got in comment, maybe the RPC rule of inbound is disabled.
i did almost a similar script not too long ago, but to check specific user on all DC machines, and there i did a checkup with test-connection first, to see if the machines are on, and then loop for process of each online machine - maybe you can do something with that too

Get List of Printer Drivers from list of Computers PowerShell

I've tried a variety of iterations of this and gotten a range of errors. I'm trying to get a a list of installed drivers off from a list of computers. None of the ways I've tried in PowerShell have piped the information into a csv. Here's the current iteration of the script.
#Load Active Directory
Import-Module activedirectory
#Load list of computers
$results = #()
$Computer = Get-Content -path 'C:\ScriptResources\computers.txt'
#Check each computer in the list
foreach($ComputerName in $Computer)
{
$results += Get-ADComputer -Filter " Name -Like '*$ComputerName*' " | Get-PrinterDriver; Start-Sleep -milliseconds 500
}
#Export to CSV file
$results | export-csv 'C:\ScriptResults\InstalledPrinters.csv'
I've also used it with just the Get-Printer command and got the following error.
Get-Printer : No MSFT_Printer objects found with property 'Name' equal to 'Redacted'. Verify the value of the
property and retry.
Depending what I've fed the $Computer file I'll get different errors. I've also gotten the RPC server is unavailable and Error Spooler Service Not Running. I have domain wide privileges and I checked the print spooler service and it is running.
The reason I think this is odd is that I have .bat tool that I use that gets printer info from a singular host and I don't run into any issues. The reason I'm trying to put this in PowerShell is because 1) I want to do the whole domain and 2) PowerShell formats its outputs in a more useable fashion.
wmic /node:%ComputerIP% path win32_printer get deviceid, drivername, portname
Additionally, I've also tried the following in the $results function of the script
$results += Get-WmiObject -class Win32_printer -ComputerName name, systemName, shareName
This didn't give errors. What it did instead is that for each computer in the list of computers it checked the computer I was running the script from for its printers and output on each line which printers were installed on my computer.
I'm at a loss and any help would be appreciated. Thanks!
Just so this is closed out. Vivek's answer ended up working.
$results += Get-WmiObject -class Win32_printer -ComputerName $Computer | Select name, systemName, shareName
The RPC issue I was getting was that the list of computers were all turned off for some reason (remote site + different time zone + doing the testing during second shift). Normally, everything remains on though. So that was just an anomaly.
Thanks for the help!

Find NIC by IP address

I need to be able to find a NIC by IP address, whether full or partial. So writing something like:
Get-NIC-By-IP 10.10.*
Could return:
Ethernet
I know how to do this in Bash but haven't been able to find a PowerShell solution to this.
For versions of Windows and/or PowerShell that do not support Get-NetIPAddress, you can get the requisite information with a combination of the WMI queries for the classes Win32_NetworkAdapterConfiguration and Win32_NetworkAdapter:
$Configs = Get-WMIObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled='TRUE'" | Where-Object {$_.IPAddress -like "192.168.*"}
ForEach ($Config in $Configs) {
Get-WMIObject -Class Win32_NetworkAdapter -Filter "Index=$($Config.Index)" | Select-Object NetConnectionID,Description
}
By using the following command you will receive every interface which matches the IP-addres which you mention in the match clause.
Get-NetIPAddress | ?{ $_.AddressFamily -eq "IPv4" -and ($_.IPAddress -match "192.")} | Select-Object InterfaceAlias
In my case this is:
InterfaceAlias
--------------
Ethernet 2
Ethernet
Of course, you can modify the output if necessary.
Supplement for old OS'es
You can't run this script on old Windows browsers as the cmdlet isn't included according to this thread on TechNet: https://social.technet.microsoft.com/Forums/office/en-US/dcc966a1-24c2-4ae4-b39d-b78df52b6aef/install-of-powershell-3-on-windows-7-seems-to-be-missing-modules?forum=winserverpowershell
There are many cmdlets in Powershell for Windows 8 and Server 2012 (PS V3) that are not included in the V3 release for Windows 7.  An example would be Get-NetIPAddress, and many other network-related cmdlets.
Then again, it might be a good idea to upgrade the OS to a supported version (if possible of course).

Get Chrome version for remote devices

I am using PS V3.0 to check Google chrome version:
get-content -Path C:\Support\assets.txt | ForEach-Object ({get-wmiobject win32_product -ComputerName $_ | where-Object {$_.name -eq "google chrome"} |FT version})
{write-host "$_"}
Inside the txt file are the IP addresses of remote devices.
The command is working fine and gives me Chrome version, but I cannot include IP address inside the loop.
It gives me only chrome version without information to which remote device it's from. I would like to get something like this :
IP address - Chrome version
IP address - Chrome version
As far as I understand this it should be Foreach (action){do something}?
Also is there any chance to remove word "version" from the input?
Ok, you've made some very innocent beginner type mistakes, but that's fairly easily remedied.
Let's start with ft. ft is short for Format-Table. Generally speaking, you only use a Format- command when you are trying to output something. You are trying to use the results of that, not output it, so we need to drop the ft. Instead use the Select-Object cmdlet (or more commonly used is the shorter select).
get-content -Path C:\Support\assets.txt | ForEach-Object ({get-wmiobject win32_product -ComputerName $_ | where-Object {$_.name -eq "google chrome"} |Select version})
Ok, that gets you an array of objects that only have the Version property. Not super useful, especially when you wanted to know what computer each is associated with! So, that's a good lesson in general, but not very practical here. Let's move on with actually making things better!
You are making things harder than need be by piping things to a ForEach loop like that. You are making separate Get-WMIObject calls against each IP address. If we look at get-help get-wmiobject -parameter computername we can see that it accepts an array of strings. So we can make 1 call against multiple targets, which should help speed things up a bit.
$IPList = get-content -Path C:\Support\assets.txt
Get-WMIObject win32_product -ComputerName $IPList | Where{$_.Name -eq 'Google Chrome'}
That should speed up your results a bit, but what will make things a whole lot faster is to use Get-WMIObject's -Filter parameter instead of Where. The reason is that the provider is more efficient at filtering its own objects, and returning just what you want, than PowerShell is as filtering things. Also, this reduces the data sent back from the remote machines, so you are only getting the data you want from them rather than potentially hundreds of results per machine, and then parsing down to just the ones you want. Essentially you have all of the computers' processors working on your problem, instead of just yours. So let's use the -Filter parameter:
$IPList = get-content -Path C:\Support\assets.txt
Get-WMIObject win32_product -ComputerName $IPList -Filter "Name='Google Chrome'"
Ok, things should come back a whole lot faster now. So down to the last item, you want the computer name for what each version was found on. Good news, you already have it! Well, we have the actual name of the computer, not the IP address that you specified. It is not displayed by default, but each one of those results has a PSComputerName property that you can refer to. We can simply pipe to Select and specify the properties that we want:
$IPList = get-content -Path C:\Support\assets.txt
Get-WMIObject win32_product -ComputerName $IPList -Filter "Name='Google Chrome'" | Select PSComputerName,Version
That's probably going to get you results that you're happy with. If not, you can run it through a ForEach loop similarly to how you were, and format it like you specified:
$IPList = get-content -Path C:\Support\assets.txt
ForEach($IP in $IPList){
$Version = Get-WMIObject win32_product -ComputerName $IP -Filter "Name='Google Chrome'" | Select -Expand Version
"$IP - $Version"
}