# Powershell printer mapping script

**URL:** <https://forums.powershell.org/t/powershell-printer-mapping-script/15174>\
**Category:** PowerShell Help\
**Created:** [November 3, 2020, 2:45am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174 "2020-11-03T02:45:17Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![bobestel20](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@bobestel20](https://forums.powershell.org/u/bobestel20)\
**Post date:** [November 3, 2020, 2:45am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/1 "2020-11-03T02:45:17Z")

</div>

Hello all, I am after some help/advice on some powershell writing.

I am trying to move our company away from GPP printers to a powershell script with csv lookup.

Numerous reasons but mainly GPP (on users) when mapping printers it can slow logins if a particular printer that a user/device maps is offline.

Base script so far

```
$csv = "C:\temp\printers.csv"
$addprinters = Import-Csv $csv

foreach ($Computer in $addprinters){
If ($Computer.pcname -eq $env:computername) {
$Printers = ($Computer.printers).split(";")
foreach ($Printer in $Printers) {Add-Printer -connectionname $Printer -ErrorAction SilentlyContinue}

(New-Object -ComObject WScript.Network).SetDefaultPrinter("$($Computer.defaultprinter)")
}
}
```

CSV info

```
name, printers, defaultprinter

X-Client-01, \\servername\printer1

X-Client-02, \\servername\printer1

Y-Client-01, \\servername\printer1

Y-Client-02, \\servername\printer1

Y-Client-01, \\servername\printer1

Y-Client-01, \\servername\printer2

Y-Client-01, \\servername\printer3
```

It doesn’t go as far as I would like to and now as tidy i am going in circles with it

I would prefer the device name to be condensed example if it was an if statement in vbs `if(left(ucase(computername),9) = “Y-Client-”`

So for example that any client that starts y-client- will be mapped the printer specified in the printers tab, then one step further so that multiple printers can be added to those devices or to a single device but based on just one line in the csv.

Example

X-Client-02 gets \server\printer1, \server\printer2, \server\printer3, with a default being \server\printer2

any device named like Y-Client- gets \server\printer4,\server\printer1,\server\printer6, default being \server\printer1

&nbsp;

many thanks

---

<div class="post-metadata">

**Author:** ![ralphmwr](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/ralphmwr/32/1064_2.png) [@ralphmwr](https://forums.powershell.org/u/ralphmwr)\
**Post date:** [November 3, 2020, 4:05am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/2 "2020-11-03T04:05:20Z")

</div>

Based on your post, here are my assumptions. Please correct me if I’m wrong:

1. Each computer will run this script.
2. Each computer will lookup it's partial computername (first part minus the sequenced number) in the csv. Should match only one line in csv.
3. Once the script finds it's partial computername, it will map the corresponding printers in the csv.

With those assumptions, I would probably do something like this:
```
#find and select the corresponding object. assumes only one line in the csv will match
$printerconfig = Import-Csv "C:\temp\printers.csv" |
                    Where-Object {$env:COMPUTERNAME -like "$($_.pcname)*" }

#map each printer  
$printerconfig.printers -split “;” |  
ForEach-Object {Add-Printer -connectionname $\_ -ErrorAction SilentlyContinue}

#set default printer  
(New-Object -ComObject WScript.Network).SetDefaultPrinter(“$($printerconfig.defaultprinter)”)
```
  
&nbsp;

---

<div class="post-metadata">

**Author:** ![bobestel20](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@bobestel20](https://forums.powershell.org/u/bobestel20)\
**Post date:** [November 4, 2020, 12:19am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/3 "2020-11-04T00:19:50Z")

</div>

Hi Mike R.

Yes you assume correctly, each computer will run this script at user logon, find its one corresponding line and map multiple printers or possibly a singular printer, set one of them to default and that could be based on full hostname or partial hostname, as we could use both.

Thank you for your script, I seem to have issue with the line adding the printers. Cannot validate argument on parameter ‘ConnectionName’. The argument is null or empty.

ForEach-Object {Add-Printer -connectionname $\_ -ErrorAction SilentlyContinue}

Many thanks again

---

<div class="post-metadata">

**Author:** ![richgardener](https://avatars.discourse-cdn.com/v4/letter/r/9f8e36/32.png) [@richgardener](https://forums.powershell.org/u/richgardener)\
**Post date:** [November 4, 2020, 12:44am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/4 "2020-11-04T00:44:31Z")

</div>

The example CSV has only one client / printer per line, rather the one client / mulitple printers serperated by a “;”. So I’m not sure what this line;

$printerconfig.printers -split “;”

would be returning as there is nothing to be split.

&nbsp;

---

<div class="post-metadata">

**Author:** ![bobestel20](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@bobestel20](https://forums.powershell.org/u/bobestel20)\
**Post date:** [November 4, 2020, 3:12am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/5 "2020-11-04T03:12:12Z")

</div>

Richgardener42, sorry i clarified the multiple mappings lower down on my post with an example. X-Client-02 gets \server\printer1, \server\printer2, \server\printer3, with a default being \server\printer2

There are more than one on each row in the CSV

---

<div class="post-metadata">

**Author:** ![tonyd](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/tonyd/32/1041_2.png) [@tonyd](https://forums.powershell.org/u/tonyd)\
**Post date:** [November 4, 2020, 6:03am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/6 "2020-11-04T06:03:25Z")

</div>

I think the Split may have been a typo. Should have been a comma for the separator.

---

<div class="post-metadata">

**Author:** ![bobestel20](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@bobestel20](https://forums.powershell.org/u/bobestel20)\
**Post date:** [November 4, 2020, 10:21pm UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/7 "2020-11-04T22:21:51Z")

</div>

I am a bit confused i am using the provided code below, but i receive the errors mentioned, the x3 printers seem to add successfully on my on client test but still produce the -connection null or empty return, and the default doesn’t set even though its typed correctly for one of the printers it has just mapped.

In that example the csv is.

pcname, printers, defaultprinters

| client1 | \\server\printer1;\\server\printer2;\\server\printer3 | \\server\printer1 |

&nbsp;

$printerconfig = Import-Csv “C:\temp\printers.csv” | Where-Object {$env:computername -like "$($_.pcname)\*"}  
$printerconfig.printers -split “;” | ForEach-Object {Add-Printer -ConnectionName $_ -ErrorAction SilentlyContinue}  
(New-Object -ComObject WScript.Network).SetDefaultPrinter(“$($printerconfig.defaultprinter)”)

&nbsp;

Add-Printer : Cannot validate argument on parameter ‘ConnectionName’. The argument is null or empty. Provide an argument  
that is not null or empty, and then try the command again.  
At line:3 char:82

- … s -split “;” | ForEach-Object {Add-Printer -ConnectionName $\_ -ErrorA …
- ~~
- CategoryInfo : InvalidData: (🙂 [Add-Printer], ParameterBindingValidationException
- FullyQualifiedErrorId : ParameterArgumentValidationError,Add-Printer

There is no printer called " \server\printer1".  
At line:5 char:62

- … bject WScript.Network).SetDefaultPrinter(“$($printerconfig.defaultprinter)”)
- 

```auto

```

- CategoryInfo : OperationStopped: (🙂 , COMException
- FullyQualifiedErrorId : System.Runtime.InteropServices.COMException

---

<div class="post-metadata">

**Author:** ![ralphmwr](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/ralphmwr/32/1064_2.png) [@ralphmwr](https://forums.powershell.org/u/ralphmwr)\
**Post date:** [November 5, 2020, 3:56am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/8 "2020-11-05T03:56:55Z")

</div>

Have you verified $printerconfig only contains one object and is not an array or empty? Run your first line (import-csv) and then check the value of $printerconfig to see if there is no objects or more than one object. The next step I would do to troubleshoot assuming there is only one object is check the value of $printerconfig.printers and $printconfig.printers -split “;”. Finally, I would check “$($printerconfig.defaultprinter)” Hopefully that will uncover the issue.

---

<div class="post-metadata">

**Author:** ![rob-simmers](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/rob-simmers/32/1010_2.png) [@rob-simmers](https://forums.powershell.org/u/rob-simmers)\
**Post date:** [November 5, 2020, 4:41am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/9 "2020-11-05T04:41:25Z")

</div>

It’s a bit dangerous to search for something and pipe to a command with a mandatory parameter. Take a look at the following:

```
$printerconfig = Import-Csv “C:\temp\printers.csv” | 
                 Where-Object {$env:computername -like “$($_.pcname)*”}

if ($printerconfig) {
    $printerList = $printerconfig.printers -split “,” | 
                   Where-Object -FilterScript {$_}
 
    if ($printerList) {
        foreach ($printer in $printerList){
            Add-Printer -ConnectionName $printer -ErrorAction SilentlyContinue
        }

        (New-Object -ComObject WScript.Network).SetDefaultPrinter(“$($printerconfig.defaultprinter)”)
    }
    else {
        'No printer list found for computer {0}' -f $env:computername
    }
}
else {
    'Computer {0} not found in csv' -f $env:computername
}
```

---

<div class="post-metadata">

**Author:** ![bobestel20](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@bobestel20](https://forums.powershell.org/u/bobestel20)\
**Post date:** [November 5, 2020, 12:05pm UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/10 "2020-11-05T12:05:42Z")

</div>

Mike R.

Yes following what you said, the issue seems to be identified when checking “$($printerconfig.defaultprinter)”

This is producing an extra space at beginning of any printer that listed on any row for the defaultprinter

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![ralphmwr](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/ralphmwr/32/1064_2.png) [@ralphmwr](https://forums.powershell.org/u/ralphmwr)\
**Post date:** [November 6, 2020, 3:23am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/11 "2020-11-06T03:23:04Z")

</div>

That should be pretty simple to fix. Either remove the space in your csv or you can remove it in your code. String objects have a Trim method that will remove leading and trailing spaces.

```
“$($printerconfig.defaultprinter)”.Trim()
```

&nbsp;

---

<div class="post-metadata">

**Author:** ![bobestel20](https://avatars.discourse-cdn.com/v4/letter/b/e9bcb4/32.png) [@bobestel20](https://forums.powershell.org/u/bobestel20)\
**Post date:** [November 10, 2020, 5:31am UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/12 "2020-11-10T05:31:08Z")

</div>

Mike R. the trim method helped solve it, it was strange as there wasn’t any leading spaces in my csv file.

Thanks for all the help/guide/scripts.

I think from trying the script I still have a hang in the running of the script if a printer is turned off. Like with group policy it seems to try multiple times to contact the printer before ‘force’ adding as offline therefore slowing it down.

So i am looking at adding to it so that i can force it to give up if the printer does not respond within a second or two.

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)\
**Post date:** [May 16, 2024, 8:28pm UTC](https://forums.powershell.org/t/powershell-printer-mapping-script/15174/13 "2024-05-16T20:28:21Z")

</div>


