Programmatically updating network printer drivers - powershell

this is a deployment issue I'm hoping to solve with some simple Powershell:
When doing 32 bit Windows XP to 64 Bit Windows 7 migration, USMT is
migrating all the network printers, which is great. As the drivers
are obviously not correct though, the driver needs to be manually
upgraded (right click printer --> Update Driver).
Is there a WMI function or Powershell cmdlet for this action? I cant seem to find any
documentation on it! As our USMT task sequence is separate from the
deployment and runs under the migrated user's context I'm sure it
would work. If I could just get the right syntax, add a Powershell
script at the end of the TS that would be perfect.
I'm basically looking for the function that would have the same result as right-clicking the printer and clicking 'Update Driver'. I've cross posted here from the MDT forums as I think this would probably be more appropriate!
I've looked at Win32_Printer class but doesn't look like it has what I need.

How I understand it, doing a RC-> Update Driver is not really the correct way to manage print drivers.
Update driver is designed to update a driver from Version X to the next Version Y and not really the correct way to change the driver from a Win XP driver to a Win 7 driver (i.e. if the XP driver is at version 1.0, and the Win 7 driver is at 1.0, then running Update driver will not do anything because the versions will be the same).
The #1 and best option is to use PowerShell remove the printers, and re-add them (which will then also install the Windows 7 drivers). That way you will guarantee that they will work.
The script will be something like this:
#Get list of all the printers on the machine
$printers = gwmi win32_printer
#Save default Printer
$DefaultPrinter = $printers | where{$_.Default} | Select ShareName
#Create a list of all the printers we want to delete (in this case I am deleting all network printers)
$PrintersToDelete = $printers | where{$_.Network -eq $true}
#Create a list of all the printers we want to add (in this case, all network printers I just deleted)
$PrintersToAdd = $printers | where{$_.Network -eq $true} | Select Name
#Delete the printers I want to delete
$PrintersToDelete | foreach{$_.delete()}
#Add back all printers we want to add
$PrintersToAdd | foreach{(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection($_.Name)}
#Get list of all the new printers on the machine
$printers = gwmi win32_printer
#Set the default printer
$NewDefaultPrinter = $printers | where{$_.DeviceID -match $DefaultPrinter}
$NewDefaultPrinter.SetDefaultPrinter()

Related

Verify driver install through powershell

I need to install a driver on a bunch of systems. (it should have come from MS but we are using kace for patching so i cant use wsus to push it out) So i found this oneliner RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 %path to inf%
Next is to put a check into it so it looks if the driver is installed first but I am having trouble finding the driver. I made an assumption that guidid or class from .inf will provide me with the info i need to check.
[Version]
Signature="$Windows NT$"
Class=SmartCard
ClassGuid={990A2BD7-E738-46c7-B26F-1CF8FB9F1391}
Provider=%ProviderName%
CatalogFile=delta.cat
DriverVer=08/11/2015,8.4.9.0"
Get-WmiObject Win32_PnPSignedDriver -Property * | where {$_.ClassGuid -like
"990A2BD7-E738-46c7-B26F-1CF8FB9F1391"}
but I can not find the driver installed. I list all drivers and attempt to scroll through them to find this one and it's not there or it's called something else now.
eventual goal is something like this
if (!(Get-WmiObject Win32_PnPSignedDriver| select devicename, classguid |
where {$_.classguid -like "*990A2BD7-E738-46c7-B26F-1CF8FB9F1391*"})) {echo
do stuff} else { echo dont do stuff}
Any help in being able to identify if the driver is installed or not would be appreciated.
A little googling goes a long way as this has been asked a few times before. Here is a WMIC query against all the installed drivers on the system, then filters out everything except the smartcard class using the classGUID.
Get-WmiObject Win32_PnPSignedDriver| where-object {$_.ClassGUID -eq "{50DD5230-BA8A-11D1-BF5D-0000F805F530}"} |Select *
Here is what got me to my answer if you need additional clarification.
How do I get all the smart card readers on my system via WMI?
https://superuser.com/questions/567927/get-driver-version-via-command-line-windows
https://blogs.technet.microsoft.com/askperf/2012/02/17/useful-wmic-queries/

Task sequence variable for OS, I want to install

I'm verry beginer in powershell, I'm wonking in a project, the goal it's to set the Biossetting like disabling or enabling the secureBoot and UEFI mode, while installing windows 7 or 10 by MDT.
I'm working with Dell and hp computer, I have the script for setting the bios of hp or dell
Hp:
$bios=Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class HP_BIOSSettingInterface
$bios.SetBIOSSetting("UEFI Boot Options", "Enable","")
Dell:
(Get-WmiObject DCIM_BIOSService -namespace root\dcim\sysman -ComputerName .).SetBIOSAttributes($null,$null,"Secure Boot","1")
Then, my first problem these command is not working in any computer I need to install some modules, some cmdlet from hp or dell website, I want to know if make my script ".exe", it's gonna work in every-computer ?
Because I need to run my script with with deployement of windows.
My second and difficult task, I want to know with variable task sequence to use in my script, to detect the os of the tasksequence, I find this code in internet, after too much research in internet
$TaskPath = "$($MdtDrive):\Task Sequences"
$ControlPath = "$MDtroot\Control"
$OSPath = "$($MdtDrive):\Operating Systems"
$OS = (Get-ChildItem -Path $OSPath | Out-GridView -PassThru -Title "Select required OperatingSystem").Name
This code detect if the OS of the task sequence I want install in my computer is windos 7 or windows 10?
Thanks !
If I recall correctly from my days of systems deployment, Dell and HP both make dedicated tools for settigns BIOS configuration. Just make sure you run it in WinPE. Depending on which BIOS settings you change you make even have to boot WinPE twice to make sure the OS installs the way you want.
Dell: http://en.community.dell.com/techcenter/enterprise-client/w/wiki/7532.dell-command-configure
HP: https://deploymentbunny.com/2010/10/18/enable-tpm-via-task-sequence-on-hp-boxes/
Although it is definitely possible to make these settings in WMI I would only look to it as a last resort. Windows has to be compatible with every piece of hardware, whereas Dell/HP tools are targeted at their systems. It's like using a scalpel vs a Swiss army knife.
I have some difficults I’m working in a script who set the bios configuration while installing windows 7 or 10 by MDT, then my first question is:
Wich variable I can use to identify the os of the new task sequence I mean the current os the mdt preparing to install in the computer after the user select the os during the installation.
I’m wondering if this code doying the job
$OS = Get-ChildItem -Path $OSPath | Out-GridView -PassThru -Title “Select required OperatingSystem”
$OSPath = “$($MdtDrive):\Operating Systems”

Errors setting printer settings

I am on a Server 2012 R2 system, I am working to migrate from a print server 2008 R2 environment over to my 2012 environment.
I have scripted the printer read from the old server and creation on the new server, but among other things I need to query certain settings and properties of the printer in the old environment and replicate it in the new.
For example - some of my queues on the old server are pointed to specific trays on a given printer - how do I query the old printer queue on the old server to get this information and set it in the new environment?
Additionally - Most of my printers are using the HP Universal Driver, some of them are color and we have manually set the "Device Type" to "Color". I can do a
$mysettings = get-printerproperty -computername <oldserver> -printername <queuename> -propertyname config:dynamicrender
and get the appropriate setting. Yet, when I do a
set-printerproperty -computername <newserver> -printername <queuename> -propertyname config:dynamicrender -value $mysettings.value** - it doesn't work.
I get:
I've even tried some simple stuff like setting duplex unit to being installed - as seen in this example from TechNet
I had the same issue and found that the PropertyName is case sensitive. It worked when I capitalized the letters (C,D & R) shown below.
Set-PrinterProperty -PrinterName $Printer -PropertyName "Config:DynamicRender" -Value $DeviceType

How to check if a server is running windows 2003 or Windows 2008 by checking its RDP screen, through script?

We have recently acquired a small firm having 1500 servers on which our team doesn't has access as of now although they are in domain. We need to find out how many servers are running Windows 2k3 and how many are Windows 2k8.
I know the RDP screen of both of these versions are different , for example: if we RDP a Win2k3 machine, it gives a warning notice first and once we click Ok, it takes us to the credentials screen , but in case of Win2k8, it directly takes us to Crendentials which is a proof of the OS on the server. Doing this manually for 1500 servers is a time consuming task.
Can we implement this RDP screen logic using a script to find out the Windows OS version.
I can imagine an Algorithm something like that:
Enter server name.
Invoke mstsc for that server
Verify if the dialogue box is a direct prompt for credentials or not?
If so, print Windows 2k8, else 2k3/2k.
If this logic successful on one server, I can use it in a foreach loop for all servers and export in in Excel.
With 1500 servers I'm going to assume that you have an Active Directory in place. In that case you should be able to simply run a query against AD to retrieve the desired information:
Import-Module ActiveDirectory
$server = 'somehostname'
$dc = '...' # domain controller of trusted domain
$fltr = "OperatingSystem -like '*server*'"
Get-ADComputer -Filter $fltr -Property OperatingSystem -Server $dc |
Where-Object { $_.Enabled } |
Select-Object Name, OperatingSystem |
Sort-Object OperatingSystem, Name
Pipe the result into Export-Csv to create a CSV file that you can import into Excel.

PowerShell: Firefox version check using Powershell

Trying to uninstall firefox using a powershell bat script. But i need to know which Firefox version is currently running and what is the folder name under program files/! I go lots of long script like: https://p0w3rsh3ll.wordpress.com/2012/02/19/get-firefoxinfo/
but i just want something simple which just return the current firefox version.
Firefox specifically contains a command-line option to get the version, as well as instructions on how to use it on Windows. This one-liner will get your current Firefox version (presuming you're in the right folder or your Firefox is in the system path):
$ffversion = [string](.\firefox.exe -v| Write-Output)
The | Write-Output bit is crucial, for now, due to a documented bug. The result is then converted to a string (also necessary) and saved as a variable here.
Assuming Firefox is installed in typical location:
wmic datafile where name='c:\\program files (x86)\\Mozilla Firefox\\Firefox.exe' get version
Just try below command in PowerShell -
PS> gp HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |Select DisplayName, DisplayVersion, Publisher, InstallDate, HelpLink, UninstallString |ogv
This will display a popup with all the version details of installed software. In there Add Criteria and Set the DisplayName to Firefox.
You will get the version.
On x64 machines, if you want to do it with gp, you need
PS> gp HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select DisplayName, DisplayVersion, Publisher, InstallDate, HelpLink, UninstallString |ogv
Thanks!
$firefox = (Get-Item (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe').'(Default)').VersionInfo