Errors setting printer settings - powershell

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

Related

Possible to use PowerShell's Get-AppvClientPackage to list AppV packages on a machine other than my own?

I can use Get-AppvClientPackage -all [| select name] or Get-WmiObject -Namespace root\appv -Class AppvClientPackage [|select name] to list all installed AppV packages installed on my own machine. It doesn't appear to be possible to use this cmdlet to get the AppV packages installed on another machine, without remote execution.
I am asking this question in hopes of finding something that works (see purpose) or get a definitive answer that it's not possible. There may be better options available (other than PS), but my question is simply if it is possible or not, so that if the latter is the case, we can push to develop a script (which could be run by someone with elevated privileges) to gather information needed.
Purpose: Our team doesn't have visibility into SCCM (that's another option is to have that team report on what is installed where, though sometimes we need answers quickly) and remote PS execution is restricted to one security team (which is understandable), but at times (for support or decommission purposes) we need to check to see if a specific client machine has a package installed, check what AppV packages a specific client has installed, as well as check to see which machines have a particular package installed.
If there is another module or cmdlet (or even something other than powershell or WMI) that might be able to yield the same information, suggestions are welcome.
Get-WmiObject utilizes RPC to connect to remote PCs and does not require PSRemoting. In this effort, all you need to do is add the -ComputerName parameter.
#Requires -Version 3
$Target = 'localhost'
$Params=#{
Namespace = 'root\appv'
Class = 'AppvClientPackage'
Property = 'Name'
ComputerName = $Target
}
Get-WmiObject #Params
PS C:\> Get-Help -Name 'Get-WmiObject' -Parameter 'ComputerName'
-ComputerName <String[]>
Specifies the target computer for the management operation. Enter a fully
qualified domain name (FQDN), a NetBIOS name, or an IP address. When the remote
computer is in a different domain than the local computer, the fully qualified
domain name is required.
The default is the local computer. To specify the local computer, such as in a
list of computer names, use "localhost", the local computer name, or a dot (.).
This parameter does not rely on Windows PowerShell remoting, which uses
WS-Management. You can use the ComputerName parameter of Get-WmiObject even if
your computer is not configured to run WS-Management remote commands.
Required? false
Position? named
Default value None
Accept pipeline input? False
Accept wildcard characters? false

How to disable windows firewall for all networked machines using the command line in Windows Server 2016?

I am currently building a Hyper-V lab consisting of a DC and multiple networked VMs, using Windows Server 2016. I'd like to completely disable the windows firewall for all existing and newly created VMs.
The best way that I've found to do this so far is via Group Policy for the Domain Profile. Then set Windows Firewall: Protect all network connections to disabled. What I would like to do is to have a way of scripting this out (using Powershell if possible).
I've found that by performing the above steps in the GUI, it creates a few entries in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Policies\Microsoft\WindowsFirewall\DomainProfile
In each of those entries, there is a property called EnableFirewall which is set to 0. So I tried creating all of this using Powershell like this:
New-Item -path "HKLM:\SOFTWARE\Policies\Microsoft" -name WindowsFirewall
New-Item -path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall" -name DomainProfile
New-ItemProperty -path "HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" -name EnableFirewall -value 0 -PropertyType DWord -Force
Unfortunately it doesn't seem to be working, so there must be something else that I'm missing.
Does anybody know how to completely disable the windows firewall for all networked machines using the command line in Windows Server 2016?
Setting up the Windows-Firewall for your domain-computers through computer-startup-script is not a great solution in my opinion.
You should definetly use Group Policy for this task.
GP does exactly what I want, I would just like a way of modifying GP using Powershell. I'm building a lab from scratch, and I'm looking to script as much of it as possible rather than using the gui.
I am not completely sure, what you are trying to achive.
You have created a lab now and I think you are trying to script a complete automatic built-up for future use. Is this correct?
If yes, then my solution is maybe what you are looking for:
Create a new GPO in your lab named "Firewall-Settings" for example.
Make all of your needed FireWall-Settings to the new GPO.
In Group Policy Editor open the main-node named „Group Policy Objects“. (important) Find the newly created GPO, right-click it and select "Backup":
Save the GPO-backup to a folder. (folder must exist)
The GPO is beeing saved and named like on the screenshot below (GUID):
That's it for the preparation. Now you maybe want to script the creation of the GPO with Powershell for future use and import the backup to obtain it's settings in a new environment:
New-GPO -Name "FireWall-Settings" | New-GPLink -Target "DC=mydomain,DC=local" # distinguishedName of Target-OU
Import-GPO -Path $PathtoGPOBackup -TargetName "FireWall-Settings" -BackupGpoName "FireWall-Settings"
The Script creates a GPO in the new environment with the name "FireWall-Settings" and links it to the target-OU.
After that you import the settings of the backup-GPO. All the domain-members in scope of the GPO will get the Windows-Firewall configured automatically.
Now the process is documented and fully automatic, if this is, what you are looking for.
Kind regards
open cmd prompt with elevated mode and run this:
netsh -r ComputerName -u Username -p Password -c advfirewall set allprofiles state off
If you want to do it for all the machines. Get all the ad computers using get-adcomputer. Run a foreach loop and put the variable istead of computername.
If you have the domain admin creds, then you are good to go with this.
Hope it helps.
Depending on the profile you want to disable, specify profiles (public, domain, private) using the -Name parameter. To disable all profiles for a networked machine, where $computerName array is the hostname of your DC, PC etc:
$computerName = 'DC1, PC1, MS1'
Invoke-Command -Computername $computerName -ScriptBlock {
Set-NetFirewallProfile -Name Domain, Public, Private -Enabled False
}

Programmatically updating network printer drivers

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()

Grabbing system product keys

So I'm trying to use the PS script found at http://gallery.technet.microsoft.com/scriptcenter/Get-product-keys-of-local-83b4ce97#content to pull Windows product keys from my domain remotely. However, when it hits a host it returns Exception calling “OpenRemoteBaseKey” with “2″ argument(s): “The network path was not found” instead of the product key. It should also be noted that this works locally. After poking around at the internals of the script, it seems like the offending line is
$remoteReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
Research (because I'm totally new to PoSH) indicates that this type of error gets thrown when remote registry access isn't working. Trying to hook into the registry on my test target via regedit shows that I need to have Windows Firewall: Allow inbound remote administration exception set to enabled in Group Policy. I set it and then pulled the updated policy down to the same result. What other stuff might be getting in the way of my connection?
I would recommend using PSRemoting over using the remote registry. Assuming this is set up, all you would have to do is:
$computers = #('localhost')#list of computers
#unless you are currently logged in as a domain admin
# you will need to provide credentials
$cred = Get-Credential domain\administrator
Invoke-Command -Credential $cred -ComputerName $computers -ScriptBlock {
function Get-ProductKey{
#from http://gallery.technet.microsoft.com/scriptcenter/Get-product-keys-of-local-83b4ce97
}
get-ProductKey
}| ft Computername,OSDescription,OSVersion,ProductKey
This will print out the following output:
Computername OSDescription OSVersion ProductKey
------------ ------------- --------- ----------
%name% Microsoft Windows 8 Pro 6.2.9200 XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
I used the following command through powershell, ran it as admin:
wmic /user:jc1_admin /node:pc00202 os get "SerialNumber"

Powershell - Refresh SNMP from registry or do a SNMPServiceResetEvent

I've written a powershell script that writes registry entries for network drivers to change DCB settings. Things like turning DCB on and off, defining traffic classes and bandwidth groups. After writing the values to registry sometimes you cannot see the changes with SNMP remotely. Though this is inconsistent.
I've scoured the web to see if there is a way to force SNMP to get its values from registry again. We have a script that sets the values in SNMP which automatically changes the registry. I'm trying to go the opposite way and set the values in the registry and have the MIB updated. I've tried reseting the SNMP service and network device in the script with no luck.
After modifying the registry, do a SetEvent on the global event named
"SNMPServiceResetEvent". (That is, do a CreateEvent to that named event and
then do a SetEvent). That should cause the agent to reintialize using the
current registry values.
Jeff Kelley
Microsoft / Windows CE Networking
The only thing I've found that sounds like what I need is the above quote, though futher research suggests he is talking about C++ or C#. Is there a way to do what he suggests in powershell? I found a New-Event commandlet though I'm unsure of its suitability to the current task. Code I've tried:
$snmpService = New-Event -sourceidentifier dcbScriptSnmpReset -sender SNMPServiceResetEvent -messagedata "Reset SNMP to refresh Registry"
Though there is no Set-Event commandlet and I don't know how to proceed.
Any help or leads would be much appreciated.
Thanks,
Marcus
Apparently I misunderstood how SNMP worked and now I can get it to update values entered into the registry by enabling and disabling the network adapter and stopping and starting the SNMP service:
Stop-Service $snmpService.Name
$adaptor = Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.DeviceID -eq $deviceID }
$adaptor.Disable()
$adaptor.Enable()
Start-Service $snmpService.Name