-
Notifications
You must be signed in to change notification settings - Fork 0
/
PrintMgmt.ps1
269 lines (201 loc) · 9.39 KB
/
PrintMgmt.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<#
.DESCRIPTION
This script maps or remove printers
When executed under SYSTEM authority a scheduled task is created to ensure recurring script execution on each user logon.
.NOTES
Version: 1.0
Author: Ákos Bakos / SmartCon GmbH
Creation Date: 14.06.2022
Modifications
Purpose/Change: 14.06.2022 - Initial script development
#>
[CmdletBinding()]
Param()
###########################################################################################
# Start transcript for logging
###########################################################################################
Start-Transcript -Path $(Join-Path $env:ProgramData "\Microsoft\IntuneManagementExtension\Logs\IntunePrinterMappingScript.log")
## Manual Variable Definition
########################################################
$printers = @()
$printers += [pscustomobject]@{PrinterName="FollowMe-SW";PrintServer="\\XXX.lan\FollowMe-SW";ADGroup="";Default="1"}
$printers += [pscustomobject]@{PrinterName="FollowMe-Color";PrintServer="\\XXX.lan\FollowMe-Color";ADGroup="";Default="0"}
# Override with your Active Directory Domain Name if you haven't configured the domain name as DHCP option
$searchRoot = ""
###########################################################################################
# Helper function to determine a users group membership
###########################################################################################
function Get-ADGroupMembership {
param(
[parameter(Mandatory = $true)]
[string]$UserPrincipalName
)
process {
try {
if ([string]::IsNullOrEmpty($env:USERDNSDOMAIN) -and [string]::IsNullOrEmpty($searchRoot)) {
Write-Error "Security group filtering won't work because `$env:USERDNSDOMAIN is not available!"
Write-Warning "You can override your AD Domain in the `$overrideUserDnsDomain variable"
}
else {
# if no domain specified fallback to PowerShell environment variable
if ([string]::IsNullOrEmpty($searchRoot)) {
$searchRoot = $env:USERDNSDOMAIN
}
$searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(userprincipalname=$UserPrincipalName))"
$searcher.SearchRoot = "LDAP://$searchRoot"
$distinguishedName = $searcher.FindOne().Properties.distinguishedname
$searcher.Filter = "(member:1.2.840.113556.1.4.1941:=$distinguishedName)"
[void]$searcher.PropertiesToLoad.Add("name")
$list = [System.Collections.Generic.List[String]]@()
$results = $searcher.FindAll()
foreach ($result in $results) {
$resultItem = $result.Properties
[void]$List.add($resultItem.name)
}
$list
}
}
catch {
#Nothing we can do
Write-Warning $_.Exception.Message
}
}
}
#check if running as system
function Test-RunningAsSystem {
[CmdletBinding()]
param()
process {
return [bool]($(whoami -user) -match "S-1-5-18")
}
}
###########################################################################################
# Get current group membership for the group filter capabilities
###########################################################################################
Write-Output "Running as SYSTEM: $(Test-RunningAsSystem)"
try {
#check if running as user and not system
if (-not (Test-RunningAsSystem)) {
$groupMemberships = Get-ADGroupMembership -UserPrincipalName $(whoami -upn)
} else {
# No remediation required as executed as System
}
}
catch {
#nothing we can do
}
###########################################################################################
#region Map Printer
###########################################################################################
# Add printer Only when executed as user
if (-not (Test-RunningAsSystem)) {
$PrintersForUser = @()
foreach ($printer in $Printers) {
if($printer.ADGroup -ne $null -and $printer.ADGroup.Contains(",")) {
$Agroups = $printer.ADGroup.Split(",")
foreach ($Agroup in $Agroups) {
if ($groupMemberships -contains $Agroup) {
$PrintersForUser += $printer
break
}
}
} else {
if ($groupMemberships -contains $printer.ADGroup -or [String]::IsNullOrWhiteSpace($printer.ADGroup)) {
$PrintersForUser += $printer
}
}
}
Write-Output "Found the following printers to map:"
Write-Output $PrintersForUser
Foreach ($Printer in $PrintersForUser){
Try {
Write-Output "Get the status of the printer '$($Printer.PrintServer)' on the print server"
$PrinterServerStatus = (Get-Printer -ComputerName (([URI]($Printer.PrintServer)).host) -Name $Printer.PrinterName).PrinterStatus
# Only perform check if the printer on the print server is not offline
If ($PrinterServerStatus -ne "Offline") {
# Throw error is printer doesn't exist
If (!(Get-Printer -Name $Printer.PrintServer -ErrorAction SilentlyContinue)){
Write-Output "Printer not mapped, adding '$($Printer.PrintServer)'"
Add-Printer -ConnectionName $Printer.PrintServer
if($Printer.Default -eq 1){
$PrinterDefault = Get-CimInstance -Class Win32_Printer -Filter 'Name LIKE "%FollowMe-SW%"'
Write-Output "Setting printer as default: '$($PrinterDefault)'"
Invoke-CimMethod -InputObject $PrinterDefault -MethodName SetDefaultPrinter
}
}
} else {
Write-Output "Printer is offline or Sppoler not running"
$Printer
}
} Catch {
Write-Output "Failed to map the printer"
$Printer
$_
}
}
}
#end region
###########################################################################################
# End & finish transcript
###########################################################################################
Stop-transcript
###########################################################################################
# Done
###########################################################################################
#!SCHTASKCOMESHERE!#
###########################################################################################
# If this script is running under system (IME) scheduled task is created (recurring)
###########################################################################################
if (Test-RunningAsSystem) {
Start-Transcript -Path $(Join-Path $env:ProgramData "\Microsoft\IntuneManagementExtension\Logs\IntunePrinterMappingScheduledTask.log")
Write-Output "Running as System --> creating scheduled task which will run on user logon"
###########################################################################################
# Get the current script path and content and save it to the client
###########################################################################################
$currentScript = Get-Content -Path $($PSCommandPath)
$schtaskScript = $currentScript[(0) .. ($currentScript.IndexOf("#!SCHTASKCOMESHERE!#") - 1)]
$scriptSavePath = $(Join-Path -Path ${env:ProgramFiles(x86)} -ChildPath "IntunePrinterMappingGenerator")
if (-not (Test-Path $scriptSavePath)) {
New-Item -ItemType Directory -Path $scriptSavePath -Force
}
$scriptSavePathName = "IntunePrinterMapping.ps1"
$scriptPath = $(Join-Path -Path $scriptSavePath -ChildPath $scriptSavePathName)
$schtaskScript | Out-File -FilePath $scriptPath -Force
###########################################################################################
# Create dummy vbscript to hide PowerShell Window popping up at logon
###########################################################################################
$vbsDummyScript = "
Dim shell,fso,file
Set shell=CreateObject(`"WScript.Shell`")
Set fso=CreateObject(`"Scripting.FileSystemObject`")
strPath=WScript.Arguments.Item(0)
If fso.FileExists(strPath) Then
set file=fso.GetFile(strPath)
strCMD=`"powershell -nologo -executionpolicy ByPass -command `" & Chr(34) & `"&{`" &_
file.ShortPath & `"}`" & Chr(34)
shell.Run strCMD,0
End If
"
$scriptSavePathName = "IntunePrinterMapping-VBSHelper.vbs"
$dummyScriptPath = $(Join-Path -Path $scriptSavePath -ChildPath $scriptSavePathName)
$vbsDummyScript | Out-File -FilePath $dummyScriptPath -Force
$wscriptPath = Join-Path $env:SystemRoot -ChildPath "System32\wscript.exe"
###########################################################################################
# Register a scheduled task to run for all users and execute the script on logon
###########################################################################################
$schtaskName = "IntunePrinterMapping"
$schtaskDescription = "Map printers from intune-printer-mapping-generator."
$trigger = New-ScheduledTaskTrigger -AtLogOn
#Execute task in users context
$principal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -Id "Author"
#call the vbscript helper and pass the PosH script as argument
$action = New-ScheduledTaskAction -Execute $wscriptPath -Argument "`"$dummyScriptPath`" `"$scriptPath`""
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$null = Register-ScheduledTask -TaskName $schtaskName -Trigger $trigger -Action $action -Principal $principal -Settings $settings -Description $schtaskDescription -Force
Start-ScheduledTask -TaskName $schtaskName
Stop-Transcript
}
###########################################################################################
# Done
###########################################################################################