Powershell printer installation script - powershell

I'm trying to create a login script that performs a few actions. I need it to complete the following.
Check and record the current default printer.
Delete all printers.
Install a specific list of printers.
Set the default printer back to what the default printer was previously.
I need to do this because we've made some printer name changes on the network and we want to re-map all of the printers with the new names and also install some additional printers. I currently have a batch file calling a .ps1 file. Here's the code from both files.
Login.bat
#echo off
powershell -command Set-ExecutionPolicy Unrestricted -force
Powershell -command " & '\\server\share\MyPSScript.ps1'"
Login.ps1
# Save current default printer.
Get-WmiObject -Query " SELECT * FROM Win32_Printer WHERE Default=$true" | foreach {$_.portname} -OutVariable CurDefPrinter
# Deletes all network printers.
Get-WmiObject Win32_Printer | where{$_.Network -eq ‘true‘} | foreach{$_.delete()}
# Maps all network printers.
add-printer -connectionname "\\server\ricoh"
add-printer -connectionname "\\server\hp"
# Set default printer
(Get-WmiObject -Class Win32_Printer -Filter "portame='$CurDefPrinter'").SetDefaultPrinter()
When I run this, I get this error.
C:\Temp\Scripts>Login.bat
C:\Temp\Scripts>REM #echo off
10.0.0.155
Get-WmiObject : Invalid query "select * from Win32_Printer where portame='10.0.0.155'"
At \\server\share\login.ps1:12 char:2
+ (Get-WmiObject -Class Win32_Printer -Filter "portame='$CurDefPrinter' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
You cannot call a method on a null-valued expression.
At \\server\share\Login.ps1:12 char:1
+ (Get-WmiObject -Class Win32_Printer -Filter "portame='$CurDefPrinter' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Any help would be greatly appreciated!

You spelled PortName wrong so nothing was being returned and you were calling a method on ($null)
(Get-WmiObject -Class Win32_Printer -Filter "portname='$CurDefPrinter'").SetDefaultPrinter()

If you dont need to use the Query and Filter option you can do it like this:
#to get the current default printer
$default = Get-WmiObject -Class Win32_Printer | Where-Object {$_.Default -eq "true"}
#to reset the default printer
$default.SetDefaultPrinter()
Atleast it works at my enviroment.

Related

PowerShell script to get logged in user

I am looking to run a script on a remote machine using an automation tool that runs the scripts in the system context.
What I have so far:
$userId = Get-Process -IncludeUserName explorer | % username | sort Username -Unique
Write-Host $userid.ToLower()
Results:
Get-Process : A parameter cannot be found that matches parameter name
'IncludeUserName'.
At line:1 char:39
+ $userId = Get-Process -IncludeUserName <<<< explorer | % username | sort Username -Unique
+ CategoryInfo : InvalidArgument: (:) [Get-Process], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetProcessCommand
ToLower : You cannot call a method on a null-valued expression.
At line:2 char:27
+ Write-Host $userid.ToLower <<<< ()
+ CategoryInfo : InvalidOperation: (ToLower:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Any ideas how to help this script? Or the cause of the errors?
The error says it all; the switch -IncludeUserName is not available on your computer. That's because it requires PowerShell 4.0 or above like Ansgar mentioned.
One solution is to install the latest Windows Mangement Framework (WMF) which includes the latest version of PowerShell.
You can also use the WMI-class Win32_Process to get the user and/or domain by calling the object's GetOwner()-method. Ex:
Get-WmiObject -Class Win32_Process -Filter "Name = 'explorer.exe'" |
ForEach-Object { $_.GetOwner() | % { "$($_.Domain)\$($_.User)" } } |
Sort-Object -Unique
the following script might help you. I'm not completely certain if the invoked command will get the remote logged in user, because I'm not on a work computer right now but it came from the internet so it must be true.
$Computers = (Get-Content "\\<sharedrive\<directory>\Computers.txt)
Foreach ($Computer in $Computers){ `
Invoke-Command -ComputerName $Computer -ScriptBlock `
{Get-WMIObject -Class Win32_ComputerSystem).Username} `
}

Unable to get PowerShell code to work

I am trying to run a script from my Active Directory host to the other hosts on the network that will pull device info for each of the hosts.
The code I am using is:
# Exports Local System Information to CSV
# Run this PowerShelll script at log on to collect PC information to a CSV file on a network share
# Thom McKiernan 28/08/2014
#Get hostnames
#$Computers = Get-Content ("C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\ComputerListAug2015.txt") -ErrorAction SilentlyContinue
foreach ($computer in Get-Content "C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\ComputerListAug2015.txt")
{
# Collect the info from WMI
$computerSystem = get-wmiobject Win32_ComputerSystem -Computer $computer.$deviceinfile
$computerBIOS = get-wmiobject Win32_BIOS -Computer $computer.$deviceinfile
$computerOS = get-wmiobject Win32_OperatingSystem -Computer $computer.$deviceinfile
$computerCPU = get-wmiobject Win32_Processor -Computer $computer.$deviceinfile
$computerHDD = Get-WmiObject Win32_LogicalDisk -ComputerName $computer.$deviceinfile -Filter drivetype=3
$macAddress = Get-WmiObject win32_networkadapterconfiguration -Computer $computer.$deviceinfile -Filter "IpEnabled = TRUE"
#Build the CSV file
$csvObject = New-Object PSObject -property #{
"PCName" = $computerSystem.Name
"Manufacturer" = $computerSystem.Manufacturer
"Model" = $computerSystem.Model
"SerialNumber" = $computerBIOS.SerialNumber
"RAM" = "{0:N2}" -f ($computerSystem.TotalPhysicalMemory/1GB) + "GB"
"HDDSize" = "{0:N2}" -f ($computerHDD.Size/1GB) + "GB"
"HDDFree" = "{0:P2}" -f ($computerHDD.FreeSpace/$computerHDD.Size) + "GB"
"CPU" = $computerCPU.Name
"OS" = $computerOS.caption
"SP" = $computerOS.ServicePackMajorVersion
"User" = $computerSystem.UserName
"BootTime" = $computerOS.ConvertToDateTime($computerOS.LastBootUpTime)
"MACAddress" = $macAddress.MacAddress
}
#Export the fields you want from above in the specified order
$csvObject | Select PCName, Maufacturer, Model, SerialNumber, RAM, HDDSize, HDDFree, CPU, OS, SP, User, BootTime, MACAddress | Export-Csv 'system-info.csv' -NoTypeInformation -Append
}
# Open CSV file for review (leave this line out when deploying)
notepad system-info.csv
However, I am continuously getting the following error:
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
I have tried to set up the txt file as just computer names (exported from Active Directory) and I have tried to append each name with ".domain.com" and neither have worked.
I tried to have just my own device in the list, and no error occurred, but there was no output either. It was as if it didn't run when using "powershell -noexit .\ComputerDetails.ps1" but when I just run the script by right-clicking on it I can see the errors fly by, and an error from Notepad saying the file does not exist.
I have tried to google this issue, and found countless resources, that do not seem to help get rid of this error.
Full list of errors recieved:
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argum
ent is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:12 char:63
+ $computerSystem = get-wmiobject Win32_ComputerSystem -Computer <<<< $compute
r.$deviceinfile
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
ngValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
Shell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argum
ent is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:13 char:51
+ $computerBIOS = get-wmiobject Win32_BIOS -Computer <<<< $computer.$deviceinf
ile
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
ngValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
Shell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argum
ent is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:14 char:60
+ $computerOS = get-wmiobject Win32_OperatingSystem -Computer <<<< $computer.$
deviceinfile
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
ngValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
Shell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argum
ent is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:15 char:55
+ $computerCPU = get-wmiobject Win32_Processor -Computer <<<< $computer.$devic
einfile
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
ngValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
Shell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argum
ent is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:16 char:61
+ $computerHDD = Get-WmiObject Win32_LogicalDisk -ComputerName <<<< $computer.
$deviceinfile -Filter drivetype=3
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
ngValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
Shell.Commands.GetWmiObjectCommand
Get-WmiObject : Cannot validate argument on parameter 'ComputerName'. The argum
ent is null or empty. Supply an argument that is not null or empty and then try
the command again.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:17 char:72
+ $macAddress = Get-WmiObject win32_networkadapterconfiguration -Computer <<<<
$computer.$deviceinfile -Filter "IpEnabled = TRUE"
+ CategoryInfo : InvalidData: (:) [Get-WmiObject], ParameterBindi
ngValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Power
Shell.Commands.GetWmiObjectCommand
Attempted to divide by zero.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:27 char:53
+ "HDDFree" = "{0:P2}" -f ($computerHDD.FreeSpace/ <<<< $computerHDD.Size)
+ "GB"
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Export-Csv : A parameter cannot be found that matches parameter name 'Append'.
At C:\Users\Administrator.ESP\Documents\SoftwareAuditing\ComputerDetails\Comput
erDetails.ps1:37 char:183
+ $csvObject | Select PCName, Maufacturer, Model, SerialNumber, RAM, HDDSize, H
DDFree, CPU, OS, SP, User, BootTime, MACAddress | Export-Csv 'system-info.csv'
-NoTypeInformation -Append <<<<
+ CategoryInfo : InvalidArgument: (:) [Export-Csv], ParameterBind
ingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Comm
ands.ExportCsvCommand
The issue you are having here is that PowerShell is trying to get the property defined by $deviceinfile from the object $computer. However $computer is just a string that does not have a property $deviceinfile. Is that supposed to be a suffix as part of your naming convention?
Brief Explanation of the issue
Look at the following example
$Computer = "comp1"
$deviceinfile = "Test"
$Computer.$deviceinfile
That returned nothing since there is not "Test" property on the $computer string object. I think the result you were expecting was comp1.Test. Now look at this example.
$deviceinfile = "Test"
$computer = New-Object -TypeName PSCustomObject -Property #{Test = "Bagel"}
$Computer.$deviceinfile
We made an object with a property called Test. "Bagel" is what is returned from that code.
What you can do in your code
If this is a naming convention you need to put that into quotes to stop it from being treated like a property call. Those variable will be expanded the way you would expect them. That is of course assuming you have $deviceinfile defined before it is called.
$computerSystem = get-wmiobject Win32_ComputerSystem -Computer "$computer.$deviceinfile"
Else just remove it.
$computerSystem = get-wmiobject Win32_ComputerSystem -Computer $computer

Permissions for using gwmi win32_ntlogevent instead of get-eventog?

The problem I have: get-eventlog works (I tested by doing "run as" on the PoSH ISE). Get-WMIObject win32_ntlogevent does not. It's a perm issue of some sort. Help please.
Background:
I've built a script that uses gwmi win32_ntlogevent to pull event logs. (I chose it because it was an order of magnitude faster than either get-winevent or get-eventlog, even with filters).
However, I cannot reach some other servers in my environment. So I had the Servers group add a credential to connect under, that has some sort of Log Reader right. (not sure what they added)
Get-Eventlog:
$server = "myserver"
get-eventlog -ComputerName $server -logname "application"
(above returns results)
Get-WMIObject win32_ntlogevent does not. Neither with
Get-WmiObject win32_ntlogevent -ComputerName $server
or
$time = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime('2015/05/01 5:00:00am')
$EventQuery = #"
select
Logfile, RecordNumber, Timegenerated, TimeWritten, EventCode, EventType, Type, Category, CategoryString, SourceName, InsertionStrings, ComputerName, User, Message
from Win32_NTlogEvent
where timewritten >='$time'
and LogFile = 'system'
"# #this line must be un-recessed
gwmi -computername $server -Query $EventQuery
Instead, I get:
gwmi : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:10 char:1
+ gwmi -computername "myserver" -Query $EventQuery
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Thanks!

Win32_LogicalFileSecuritySetting returns an error for some paths, but not others

I got a script from Microsoft that uses the following method to get NTFS security settings from a remote machine.
$SharedFolderPath=[regex]::Escape("D:\UserSetup");
$SharedNTFSSecs = Get-WmiObject -Class Win32_LogicalFileSecuritySetting -Filter "Path='$SharedFolderPath'" -ComputerName $Computer
$SharedFolderPath=[regex]::Escape("C:\Program Files\AdventNet\ME\OpManager\Reports");
$SharedNTFSSecs = Get-WmiObject -Class Win32_LogicalFileSecuritySetting -Filter "Path='$SharedFolderPath'" -ComputerName $Computer
I got the paths from a previous call to Win32_Share. The first one works fine, the second gives an error:
> Get-WmiObject : Invalid query At line:1 char:118
> + $SharedFolderPath=[regex]::Escape("C:\Program Files\AdventNet\ME\OpManager\Reports"); $SharedNTFSSecs =
> Get-WmiObject <<<< -Class Win32_LogicalFileSecuritySetting -Filter
> "Path='$SharedFolderPath'" -ComputerName $Computer
> + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
> + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
The only thing different is the path:
D:\UserSetup
C:\Program Files\AdventNet\ME\OpManager\Reports
I can connect to the share and view the security permissions. I am effectively in the local administrators group and that group has full control over the problem share.
Does anyone have any clue why I'm getting an error (and consequently no resulting object)?
I beleive that this is because :
[regex]::Escape("C:\Program Files\AdventNet\ME\OpManager\Reports")
gives
C:\\Program\ Files\\AdventNet\\ME\\OpManager\\Reports
The white space is escaped also, try :
Get-WmiObject -Class Win32_LogicalFileSecuritySetting -Filter "Path='C:\\Program Files\\AdventNet\\ME\\OpManager\\Reports'" -ComputerName $Computer

Invalid Namespace when automating Get-WMIObject

I am trying to automate the retrieval of OS architecture and when I do I get an Invalid Namespace error.
foreach($i in $hosts){
$ip = $i.name
Get-WmiObject -ComputerName $ip Win32_OperatingSystem
}
If I take Get-WmiObject -ComputerName $ip Win32_OperatingSystem and replace $ip with a legit IP it works perfectly. I even added Write-Host to the front of Get-WMIObject so it would display the entire command that would run. I ran the output from Write-Host and the command completes successfully.
Error:
Get-WmiObject : Invalid namespace
At line:4 char:18
+ Get-WmiObject <<<< -ComputerName $ip Win32_OperatingSystem
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
The $hosts variable is a PSCustomObject with two noteProperty fields. The first is name and the second is user. The name field holds an IP address of the system.
It turns out there were trailing whitespaces after the IPs. I used .trim() and now everything works just fine.