Powershell Set default printer when the installation is done - powershell

I have exported my network printers to an .xml file so they can be installed on a new PC.
Also, I haveexportet the default printer to a file so you can set a default printer after the installation.
The installation works fine. The problem is that the installation of the printers has not been completed before the script try to set the default printer.
This is my script to install the printers:
#Install the printer
$PrinterList = Import-Clixml H:\Backup\printers_export.xml
foreach($Printer in $PrinterList) {
Invoke-Expression 'rundll32 printui.dll PrintUIEntry /in /q /n $($Printer.Name)'
}
# Set default printer
(New-Object -ComObject WScript.Network).SetDefaultPrinter((get-content h:\Backup\DefaultPrinter.txt))
One solution I have found is to put a Start-Sleep -s 15 after the first calls, can anyone point me to a better solution?

Add do/while loop condition to wait for default printer configuration is done. Like so:
$DP = (New-Object -ComObject WScript.Network).SetDefaultPrinter((Get-Content H:\Backup\DefaultPrinter.txt))
do {
Start-Sleep -Seconds 1
[wmi]$wmi = Get-WmiObject -Query " SELECT * FROM Win32_Printer" |
Where { $_.Name -eq 'PUT YOUR DEFAULT PRINTER NAME HERE' -and $_.Default -eq $true}
}while(-not$wmi)

This is the script right now:
Restore printer
$PrinterList = Import-Clixml H:\Backup\printers_export.xml
FOREACH ($Printer in $PrinterList) {
Invoke-Expression 'rundll32 printui.dll PrintUIEntry /in /q /n $($Printer.Name)'
}
RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters
Set Default printer
$DP = (New-Object -ComObject WScript.Network).SetDefaultPrinter((Get-Content H:\Backup\DefaultPrinter.txt))
do {
Start-Sleep -Seconds 1
[wmi]$wmi = Get-WmiObject -Query " SELECT * FROM Win32_Printer" |
Where { $.Name -eq '$DP' -and $.Default -eq $true}
}while(-not$wmi)
It does not work.
Can not find the default printer and the script keeps running.

Related

Cannot install fonts with Powershell on Windows 10

On my work computer, I don't have admin privileges.
Installing new fonts cannot be done "the easy way".
At the time I was using Windows 7, I managed to run a PowerShell script that was launched at session startup and that installed the fonts from a given folder.
Here is the code I used:
add-type -name Session -namespace "" -member #"
[DllImport("gdi32.dll")]
public static extern int AddFontResource(string filePath);
"#
$FontFolder = "C:\Users\myusername\Documents\Fonts"
$null = foreach($font in Get-ChildItem -Path $FontFolder -Recurse -Include *.ttf, *.otg, *.otf) {
Write-Host "Installing : $($font.FullName)"
$result = [Session]::AddFontResource($font.FullName)
Write-Host "Installed $($result) fonts"
}
Now that I have switched to Windows 10, I thought I could go back to installing fonts "the easy way", as it is supposed to be possible to install fonts for your user without admin privileges.
This however still does not work: there is a popup window saying that "The requested file is not a valid font file". One solution is apparently to start the Windows firewall, which of course is not allowed by my administrator... but it is already running (see Edit below)
Back to the PowerShell then. The script unfortunately does not work anymore and does not provide any interesting pointers to where the problem comes from:
Installing : C:\Users\myusername\Documents\Fonts\zilla-slab\ZillaSlab-SemiBold.otf
Installed 0 fonts
Installing : C:\Users\myusername\Documents\Fonts\zilla-slab\ZillaSlab-SemiBoldItalic.otf
Installed 0 fonts
Installing : C:\Users\myusername\Documents\Fonts\zilla-slab\ZillaSlabHighlight-Bold.otf
Installed 0 fonts
I tried using a try catch, but still have no identified error:
add-type -name Session -namespace "" -member #"
[DllImport("gdi32.dll")]
public static extern int AddFontResource(string filePath);
"#
$FontFolder = "C:\Users\myusername\Documents\Fonts"
$null = foreach($font in Get-ChildItem -Path $FontFolder -Recurse -Include *.ttf, *.otg, *.otf) {
try {
Write-Host "Installing : $($font.FullName)"
$result = [Session]::AddFontResource($font.FullName)
Write-Host $result
}
catch {
Write-Host "An error occured installing $($font)"
Write-Host "$($error)"
Write-Host "$($error[0].ToString())"
Write-Host ""
1
}
}
And the resulting output
Installing : C:\Users\myusername\Documents\Fonts\zilla-slab\ZillaSlabHighlight-Bold.otf
0
Installing : C:\Users\myusername\Documents\Fonts\zilla-slab\ZillaSlabHighlight-Regular.otf
0
Installing : C:\Users\myusername\Documents\Fonts\ZillaSlab-Light.otf
0
Any idea how to solve this issue?
Edit:
Regarding the status of the security applications, here is the McAfee status:
McAfee Data Exchange Layer OK
McAfee DLP Endpoint OK
Programme de mise à jour McAfee OK
McAfee Endpoint Security OK
"Programme de mise à jour" means "update program" in French.
I also checked the list of running services :
mpssvc service (Windows defender firewall) is running
mfefire (McAfee Firewall core service) is not running
Edit2:
My last attempt is the following:
I copied the font file manually to the $($env:LOCALAPPDATA)\Microsoft\Windows\Fonts\ folder
Using regedit, I added the entry as shown below
I restarted. Still no Bebas font in WordPad or Publisher
Here's how I do it with a com object. This works for me as non-admin based on Install fonts without administrative privileges. I can see the fonts installed to "$env:LOCALAPPDATA\Microsoft\Windows\Fonts" in the Fonts area under Settings. I have Windows 10 20H2 (it should work in 1803 or higher). I also see the fonts installed in Wordpad.
$Destination = (New-Object -ComObject Shell.Application).Namespace(20)
$TempFolder = "$($env:windir)\Temp\Fonts\"
New-Item -Path $TempFolder -Type Directory -Force | Out-Null
Get-ChildItem -Path $PSScriptRoot\fonts\* -Include '*.ttf','*.ttc','*.otf' |
ForEach {
If (-not(Test-Path "$($env:LOCALAPPDATA)\Microsoft\Windows\Fonts\$($_.Name)")) {
$Font = "$($env:windir)\Temp\Fonts\$($_.Name)"
Copy-Item $($_.FullName) -Destination $TempFolder
$Destination.CopyHere($Font)
Remove-Item $Font -Force
} else { "font $($env:LOCALAPPDATA)\Microsoft\Windows\Fonts\$($_.Name) already installed" }
}
Example REG_SZ registry entry:
dir 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Fonts*' | ft -a
Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion
Name Property
---- --------
Fonts Nunito Black (TrueType) : C:\Users\myuser\AppData\Local\Microsoft\Windows\Fonts\Nunito-Black.ttf
You can install fonts on windows using following powershell scripts.
param(
[Parameter(Mandatory=$true,Position=0)]
[ValidateNotNull()]
[array]$pcNames,
[Parameter(Mandatory=$true,Position=1)]
[ValidateNotNull()]
[string]$fontFolder
)
$padVal = 20
$pcLabel = "Connecting To".PadRight($padVal," ")
$installLabel = "Installing Font".PadRight($padVal," ")
$errorLabel = "Computer Unavailable".PadRight($padVal," ")
$openType = "(Open Type)"
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
$objShell = New-Object -ComObject Shell.Application
if(!(Test-Path $fontFolder))
{
Write-Warning "$fontFolder - Not Found"
}
else
{
$objFolder = $objShell.namespace($fontFolder)
foreach ($pcName in $pcNames)
{
Try{
Write-Output "$pcLabel : $pcName"
$null = Test-Connection $pcName -Count 1 -ErrorAction Stop
$destination = "\\",$pcname,"\c$\Windows\Fonts" -join ""
foreach ($file in $objFolder.items())
{
$fileType = $($objFolder.getDetailsOf($file, 2))
if(($fileType -eq "OpenType font file") -or ($fileType -eq "TrueType font file"))
{
$fontName = $($objFolder.getDetailsOf($File, 21))
$regKeyName = $fontName,$openType -join " "
$regKeyValue = $file.Name
Write-Output "$installLabel : $regKeyValue"
Copy-Item $file.Path $destination
Invoke-Command -ComputerName $pcName -ScriptBlock { $null = New-ItemProperty -Path $args[0] -Name $args[1] -Value $args[2] -PropertyType String -Force } -ArgumentList $regPath,$regKeyname,$regKeyValue
}
}
}
catch{
Write-Warning "$errorLabel : $pcName"
}
}
}

Calling other PowerShell scripts within a PowerShell script

I'm trying to get one master PowerShell script to run all of the others while waiting 30-60 seconds to ensure that the tasks are completed. Everything else I tried wouldn't stop/wait for the first script and its processes to complete before going through all the others at the same time and would cause a restart automatically.
Main script, run as admin:
$LogStart = 'Log '
$LogDate = Get-Date -Format "dd-MM-yyy-hh-mm-ss"
$FileName = $LogStart + $LogDate + '.txt.'
$scriptList = #(
'C:\Scripts\1-OneDriveUninstall.ps1'
'C:\Scripts\2-ComputerRename.ps1'
);
Start-Transcript -Path "C:\Scripts\$FileName"
foreach ($script in $scriptList) {
Start-Process -FilePath "$PSHOME\powershell.exe" -ArgumentList "-Command '& $script'"
Write-Output "The $script is running."
Start-Sleep -Seconds 30
}
Write-Output "Scripts have completed. Computer will restart in 10 seconds."
Start-Sleep -Seconds 10
Stop-Transcript
C:\Scripts\3-Restart.ps1
1-OneDriveUninstall.ps1:
Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0
taskkill /f /im OneDrive.exe
C:\Windows\SysWOW64\OneDriveSetup.exe /uninstall
2-ComputerRename.ps1:
$computername = Get-Content env:computername
$servicetag = Get-WmiObject Win32_Bios |
Select-Object -ExpandProperty SerialNumber
if ($computername -ne $servicetag) {
Write-Host "Renaming computer to $servicetag..."
Rename-Computer -NewName $servicetag
} else {
Write-Host "Computer name is already set to service tag."
}
The log file shows:
Transcript started, output file is C:\Scripts\Log 13-09-2019-04-28-47.txt.
The C:\Scripts\1-OneDriveUninstall.ps1 is running.
The C:\Scripts\2-ComputerRename.ps1 is running.
Scripts have completed. Computer will restart in 10 seconds.
Windows PowerShell transcript end
End time: 20190913162957
They aren't running correctly at all though. They run fine individually but not when put into one master script.
PowerShell can run PowerShell scripts from other PowerShell scripts directly. The only time you need Start-Process for that is when you want to run the called script with elevated privileges (which isn't necessary here, since your parent script is already running elevated).
This should suffice:
foreach ($script in $scriptList) {
& $script
}
The above code will run the scripts sequentially (i.e. start the next script only after the previous one terminated). If you want to run the scripts in parallel, the canonical way is to use background jobs:
$jobs = foreach ($script in $scriptList) {
Start-Job -ScriptBlock { & $using:script }
}
$jobs | Wait-Job | Receive-Job

Running commands as logged on user (remotely)

Thought I would share this quick function I made for myself, feel free to adapt it and improve it according to your needs.
Sometimes you want to run commands as the logged on user of a remote computer.
As you know, some commands show output for the user who runs it and if you run the same command with Invoke-Command, it won't return the user's information, but yours). Get-Printer is an example amongst many others.
There is no easy, quick way of running commands as the logged on user natively without any third-party apps like PsExec or others so I made this quick function that uses VBS, PS1 and Scheduled Task to make it happen.
It runs completly silently for the user (thanks to the VBS) and the output is shown in your console. Please note it assumes the remote computer has a C:\TEMP.
Created in a Windows 10, powershell v 5.1.17763.503 environement.
I don't pretend it's final and perfect, it's the simplest way I found to do what is needed and I just wanted to share it with you guys as it can be very useful!
Check the comments for explanation of the code and feel free to use it as you wish. Please share your version as I'm curious to see people improve it. A good idea would be to make it support multiple computers, but as I said it's a quick function I did I don't have too much time to put into refining it.
That being said, I had no problems using it multiple times as is :)
*Output returned is in form of a string, if you want to have a proper object, add '| ConvertFrom-String' and play with it :)
PLEASE NOTE: The surefire way of grabbing the username of who is currently logged on is via QWINSTA (since Win32_ComputerSystem - Username is only reliable if a user is logged on LOCALLY, it won't be right if a user is using RDP/RemoteDesktop). So this is what I used to grab the username, however, please note that in our french environement the name of the username property in QWINSTA is "UTILISATEUR",so you have to change that to your needs (english or other language) for it to work. If I remember correctly, it's "USERNAME" in english.
On this line:
$LoggedOnUser = (qwinsta /SERVER:$ComputerName) -replace '\s{2,22}', ',' | ConvertFrom-Csv | Where-Object {$_ -like "*Acti*"} | Select-Object -ExpandProperty UTILISATEUR
See code in the answer below.
function RunAsUser {
Param ($ComputerName,$Scriptblock)
#Check that computer is reachable
Write-host "Checking that $ComputerName is online..."
if (!(Test-Connection $ComputerName -Count 1 -Quiet)) {
Write-Host "$ComputerName is offline" -ForegroundColor Red
break
}
#Check that PsRemoting works (test Invoke-Command and if it doesn't work, do 'Enable-PsRemoting' via WMI method).
#*You might have the adjust this one to suit your environement.
#Where I work, WMI is always working, so when PsRemoting isn't, I enable it via WMI first.
Write-host "Checking that PsRemoting is enabled on $ComputerName"
if (!(invoke-command $ComputerName { "test" } -ErrorAction SilentlyContinue)) {
Invoke-WmiMethod -ComputerName $ComputerName -Path win32_process -Name create -ArgumentList "powershell.exe -command Enable-PSRemoting -SkipNetworkProfileCheck -Force" | Out-Null
do {
Start-Sleep -Milliseconds 200
} until (invoke-command $ComputerName { "test" } -ErrorAction SilentlyContinue)
}
#Check that a user is logged on the computer
Write-host "Checking that a user is logged on to $ComputerName..."
$LoggedOnUser = (qwinsta /SERVER:$ComputerName) -replace '\s{2,22}', ',' | ConvertFrom-Csv | Where-Object {$_ -like "*Acti*"} | Select-Object -ExpandProperty UTILISATEUR
if (!($LoggedOnUser) ) {
Write-Host "No user is logged on to $ComputerName" -ForegroundColor Red
break
}
#Creates a VBS file that will run the scriptblock completly silently (prevents the user from seeing a flashing powershell window)
#"
Dim wshell, PowerShellResult
set wshell = CreateObject("WScript.Shell")
Const WindowStyle = 0
Const WaitOnReturn = True
For Each strArg In WScript.Arguments
arg = arg & " " & strArg
Next 'strArg
PowerShellResult = wshell.run ("PowerShell " & arg & "; exit $LASTEXITCODE", WindowStyle, WaitOnReturn)
WScript.Quit(PowerShellResult)
"# | out-file "\\$ComputerName\C$\TEMP\RAU.vbs" -Encoding ascii -force
#Creates a script file from the specified '-Scriptblock' parameter which will be ran as the logged on user by the scheduled task created below.
#Adds 'Start-Transcript and Stop-Transcript' for logging the output.
$Scriptblock = "Start-Transcript C:\TEMP\RAU.log -force" + $Scriptblock + "Stop-Transcript"
$Scriptblock | out-file "\\$ComputerName\C$\TEMP\RAU.ps1" -Encoding utf8 -force
#On the remote computer, create a scheduled task that runs the .ps1 script silently in the user's context (with the help of the vbs)
Write-host "Running task on $ComputerName..."
Invoke-Command -ComputerName $ComputerName -ArgumentList $LoggedOnUser -ScriptBlock {
param($loggedOnUser)
$SchTaskParameters = #{
TaskName = "RAU"
Description = "-"
Action = (New-ScheduledTaskAction -Execute "wscript.exe" -Argument "C:\temp\RAU.vbs C:\temp\RAU.ps1")
Settings = (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -DontStopOnIdleEnd)
RunLevel = "Highest"
User = $LoggedOnUser
Force = $true
}
#Register and Start the task
Register-ScheduledTask #SchTaskParameters | Out-Null
Start-ScheduledTask -TaskName "RAU"
#Wait until the task finishes before continuing
do {
Write-host "Waiting for task to finish..."
$ScheduledTaskState = Get-ScheduledTask -TaskName "RAU" | Select-Object -ExpandProperty state
start-sleep 1
} until ( $ScheduledTaskState -eq "Ready" )
#Delete the task
Unregister-ScheduledTask -TaskName "RAU" -Confirm:$false
}
Write-host "Task completed on $ComputerName"
#Grab the output of the script from the transcript and remove the header (first 19) and footer (last 5)
$RawOutput = Get-Content "\\$ComputerName\C$\temp\RAU.log" | Select-Object -Skip 19
$FinalOutput = $RawOutput[0..($RawOutput.length-5)]
#Shows output
return $FinalOutput
#Delete the output file and script files
Remove-Item "\\$ComputerName\C$\temp\RAU.log" -force
Remove-Item "\\$ComputerName\C$\temp\RAU.vbs" -force
Remove-Item "\\$ComputerName\C$\temp\RAU.ps1" -force
}
#____________________________________________________
#Example command
#Note: Sometimes Start-Transcript doesn't show the output for a certain command, so if you run into empty output, add: ' | out-host' or '| out-default' at the end of the command not showing output.
$Results = RunAsUser -ComputerName COMP123 -Scriptblock {
get-printer | Select-Object name,drivername,portname | Out-host
}
$Results
#If needed, you can turn the output (which is a string for the moment) to a proper powershell object with ' | ConvertFrom-String'

How do I include the username and password in a powershell script running a window service msi

I am setting up powershell scripts to automate environment installs for a variety of systems.
I need to script the running of an MSI installer file to setup a Windows Service.
How do I include the required Username and Password to make the installation fully 'quiet'
I've gotten to:
$installFile = "C:\[path]\Installer.msi"
$username = "[ad user account]"
$password = convertto-securestring -String "[secure password]" -AsPlainText -Force
msiexec /i $installFile /quiet "UserName=$username,Password=$password"
but the provided credentials are not being accepted.
Suggestions?
First of all, thank you everyone for your help.
Reading through your suggestions and the following question in the list of “Related” suggestions got me thinking in another direction (Msi insaller passing paramenter from command prompt for Set Service Login).
A little more hunting and I found this article:
Change Service Account Username & Password–PowerShell Script
So, my new plan is to default the service account inside installer via code and then change it after installation using PowerShell.
In the source code for the windows service I have a ProjectInstaller.cs file. Opening the ProjectInstaller.Designer.cs code and looking in the InitializeComponent() method I saw the following lines:
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
Adding the following line below successfully suppresses any request for service account credentials during installation:
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;
After that I used the code sample from the TechNet article to change the account post-installation.
The final script looks something like this:
$serviceName = "Service"
$oldInstallFile = "C:\Old_Installer.msi" #Only required if upgrading a previous installation
$installFile = "C:\New_Installer.msi"
$serviceConfigSource = "C:\Config"
$serviceConfigSourceFile = "C:\Config\Service.exe.config"
$serviceConfigDestinationFile = "C:\Program Files (x86)\Service\Service.exe.config"
$username = "[UserName]"
$password = "[Password]"
#Checking for existing service installation and uninstalling it
$existingService = Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"
if($existingService)
{
Write-Host "$serviceName found. Begining the uninstall process..."
if($existingService.Started)
{
$existingService.StopService()
Start-Sleep -Seconds 5
}
msiexec /uninstall $oldInstallFile /quiet
Start-Sleep -Seconds 5
Write-Host "$serviceName Uninstalled."
}
#Install New service
Write-Host "$serviceName installation starting."
msiexec /i $newInstallFile /quiet
Start-Sleep -Seconds 5
Write-Host "$serviceName installation completed."
#copy config file
if(Test-Path $serviceConfigSource)
{
Copy-Item -Path $serviceConfigSourceFile -Destination $serviceConfigDestinationFile -Force
}
#Final service setup and start up
$newService = Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"
$changeStatus = $newService.Change($null,$null,$null,$null,$null,$null,$userName,$password,$null,$null,$null)
if ($changeStatus.ReturnValue -eq "0")
{
Write-Host "$serviceName -> Sucessfully Changed User Name"
}
if(!$newService.Started)
{
$startStatus = $newService.StartService()
if ($startStatus.ReturnValue -eq "0")
{
Write-Host "$serviceName -> Service Started Successfully"
}
}
Hope this helps people.
Try to seperate your arguments with spaces:
$installArgs = "UserName=$username Password=$password"
Afterwards you can call msiexec via:
$msiArgs = "/i ""{0}"" /qn /norestart /l*v ""C:\temp\msiInstall.log"" {1}" -f $msiLocation,$installArgs
$process = Start-Process -FilePath "$env:systemroot\system32\msiexec.exe" -ArgumentList $msiArgs -Wait -PassThru
if ($process.ExitCode -ne 0) {
Write-Error "Installation failed"
}

Powershell: Re-Install Printer depending on Username

I'm trying to learn Powershell and have no experience in any script language at all (well, except Batch a bit).
What I'm trying to do is to run this Batch command -> IF "%USERNAME%"=="Admin" GOTO Admin as a Powershell command and afterwards reinstall the users Default printer. The reason why I Need a goto is because I want to use the same script for several Users. This is what I have so far as a Batch/Powershell Hybrid
IF "%USERNAME%"=="Admin" GOTO Admin
:Admin
powershell
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\\Server\adprinter")
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\Server\adprinter")
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where ShareName = 'adprinter'"
$printer.SetDefaultPrinter()
exit
GOTO eof
I'd like to do the whole Thing in powershell but I just don't get it. I read that you can do a "goto" in powershell with a if-loop. for example that's what I have
$user = [Environment]::UserName
if ($user = Admin) do {""}
But how do I run my commands now? and how do I do another Loop for other usernames?
Thank you for your help!
EDIT:
Here is the whole script I have so far. I Need a "goto" because I have more than one User, and each of them Needs his own Printer. It would be nice to transform every Batch command into a powershell command.
#echo off
IF "%USERNAME%"=="user1" GOTO user1
IF "%USERNAME%"=="user2" GOTO user2
IF "%USERNAME%"=="user3" GOTO user3
IF "%USERNAME%"=="user4" GOTO user4
IF "%USERNAME%"=="user5" GOTO user5
:user1
powershell
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\\Server\printer1")
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\Server\printer1")
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where ShareName = 'printer1'"
$printer.SetDefaultPrinter()
exit
GOTO eof
:user2
powershell
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\\Server\printer2")
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\Server\printer2")
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where ShareName = 'printer2'"
$printer.SetDefaultPrinter()
exit
GOTO eof
:user3
powershell
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\\Server\printer3")
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\Server\printer3")
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where ShareName = 'printer3'"
$printer.SetDefaultPrinter()
exit
GOTO eof
:user4
powershell
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\\Server\printer4")
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\Server\printer4")
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where ShareName = 'printer4'"
$printer.SetDefaultPrinter()
exit
GOTO eof
:user5
powershell
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\\Server\printer5")
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\Server\printer5")
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where ShareName = 'printer5'"
$printer.SetDefaultPrinter()
exit
GOTO eof
:eof
exit
I agree with arco I like the use of HashTables and your issue is perfect for it. Take a look at my code here it should give you a good point for a Powershell Start.
$drac = #{ }
Import-Csv \\RemoteServer\Share\Folder\Powershell-scripts\Connect-rac.CSV | ForEach-Object {
$drac[$_.ServerName] = $_.IMM
}
If you look at the above this is what takes my CSV file and loads it into the hashtable
and below if how my code is used, I make it look for the computer name and if the matches then it will return the hashtable value.
if ($drac.Contains($ComputerName))
{
Write-Host "Servername : $ComputerName"
$URL = $drac[$ComputerName]
$IE = New-Object -COM 'InternetExplorer.Application'
$IE.Navigate2("http:\\$URL")
$IE.Visible = $true
}
See if this helps you.