Update use-system-center-configuration-manager-to-manage-devices-with-semm.md

This commit is contained in:
MaratMussabekov
2019-07-23 10:09:07 +05:00
committed by GitHub
parent 84fecf3c6d
commit 65cff46520

View File

@ -103,39 +103,45 @@ The sample scripts include examples of how to set Surface UEFI settings and how
### Specify certificate and package names
The first region of the script that you need to modify is the portion that specifies and loads the SEMM certificate, and also indicates the names for the SEMM configuration package and SEMM reset package. The certificate and package names are specified on lines 56 through 67 in the ConfigureSEMM.ps1 script:
The first region of the script that you need to modify is the portion that specifies and loads the SEMM certificate, and also indicates SurfaceUEFIManager version, the names for the SEMM configuration package and SEMM reset package. The certificate name and SurfaceUEFIManager version are specified on lines 56 through 73 in the ConfigureSEMM.ps1 script:
```
56 $WorkingDirPath = split-path -parent $MyInvocation.MyCommand.Definition
57 $packageRoot = "$WorkingDirPath\Config"
58
59 if (-not (Test-Path $packageRoot)) { New-Item -ItemType Directory -Force -Path $packageRoot }
60 Copy-Item "$WorkingDirPath\FabrikamOwnerSigner.pfx" $packageRoot
61
62 $privateOwnerKey = Join-Path -Path $packageRoot -ChildPath "FabrikamOwnerSigner.pfx"
63 $ownerPackageName = Join-Path -Path $packageRoot -ChildPath "FabrikamSignerProvisioningPackage.pkg"
64 $resetPackageName = Join-Path -Path $packageRoot -ChildPath "FabrikamUniversalResetPackage.pkg"
65
66 # If your PFX file requires a password then it can be set here, otherwise use a blank string.
67 $password = "1234"
58 $certName = "FabrikamSEMMSample.pfx"
59 $DllVersion = "2.26.136.0"
60
61 $certNameOnly = [System.IO.Path]::GetFileNameWithoutExtension($certName)
62 $ProvisioningPackage = $certNameOnly + "ProvisioningPackage.pkg"
63 $ResetPackage = $certNameOnly + "ResetPackage.pkg"
64
65 if (-not (Test-Path $packageRoot)) { New-Item -ItemType Directory -Force -Path $packageRoot }
66 Copy-Item "$WorkingDirPath\$certName" $packageRoot
67
68 $privateOwnerKey = Join-Path -Path $packageRoot -ChildPath $certName
69 $ownerPackageName = Join-Path -Path $packageRoot -ChildPath $ProvisioningPackage
70 $resetPackageName = Join-Path -Path $packageRoot -ChildPath $ResetPackage
71
72 # If your PFX file requires a password then it can be set here, otherwise use a blank string.
73 $password = "1234"
```
Replace the **FabrikamOwnerSigner.pfx** value for the **$privateOwnerKey** variable with the name of your SEMM Certificate file on both lines 60 and 62. The script will create a working directory (named Config) in the folder where your scripts are located, and will then copy the certificate file to this working directory.
Replace the **FabrikamSEMMSample.pfx** value for the **$certName** variable with the name of your SEMM Certificate file on line 58. The script will create a working directory (named Config) in the folder where your scripts are located, and will then copy the certificate file to this working directory.
Replace the **FabrikamSignerProvisioningPackage.pkg** and **FabrikamUniversalResetPackage.pkg** values on lines 63 and 64 to define the **$ownerPackageName** and **$resetPackageName** variables with your desired names for the SEMM configuration and reset packages. These packages will also be created in the Config directory and hold the configuration for Surface UEFI settings and permissions generated by the script.
Owner pakage and reset pakage will also be created in the Config directory and hold the configuration for Surface UEFI settings and permissions generated by the script.
On line 67, replace the value of the **$password** variable, from 1234, to the password for your certificate file. If a password is not required, delete the **1234** text.
On line 73, replace the value of the **$password** variable, from 1234, to the password for your certificate file. If a password is not required, delete the **1234** text.
>[!Note]
>The last two characters of the certificate thumbprint are required to enroll a device in SEMM. This script will display these digits to the user, which allows the user or technician to record these digits before the system reboots to enroll the device in SEMM. The script uses the following code, found on lines 144-149, to accomplish this:
>The last two characters of the certificate thumbprint are required to enroll a device in SEMM. This script will display these digits to the user, which allows the user or technician to record these digits before the system reboots to enroll the device in SEMM. The script uses the following code, found on lines 150-155, to accomplish this:
```
144 # Device owners will need the last two characters of the thumbprint to accept SEMM ownership.
145 # For convenience we get the thumbprint here and present to the user.
146 $pw = ConvertTo-SecureString $password -AsPlainText -Force
147 $certPrint = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
148 $certPrint.Import($privateOwnerKey, $pw, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::DefaultKeySet)
149 Write-Host "Thumbprint =" $certPrint.Thumbprint
150 # Device owners will need the last two characters of the thumbprint to accept SEMM ownership.
151 # For convenience we get the thumbprint here and present to the user.
152 $pw = ConvertTo-SecureString $password -AsPlainText -Force
153 $certPrint = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
154 $certPrint.Import($privateOwnerKey, $pw, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::DefaultKeySet)
155 Write-Host "Thumbprint =" $certPrint.Thumbprint
```
Administrators with access to the certificate file (.pfx) can read the thumbprint at any time by opening the .pfx file in CertMgr. To view the thumbprint with CertMgr, follow this process:
@ -153,46 +159,47 @@ Administrators with access to the certificate file (.pfx) can read the thumbprin
### Configure permissions
The first region of the script where you will specify the configuration for Surface UEFI is the **Configure Permissions** region. This region begins at line 202 in the sample script with the comment **# Configure Permissions** and continues to line 238. The following code fragment first sets permissions to all Surface UEFI settings so that they may be modified by SEMM only, then adds explicit permissions to allow the local user to modify the Surface UEFI password, TPM, and front and rear cameras:
The first region of the script where you will specify the configuration for Surface UEFI is the **Configure Permissions** region. This region begins at line 210 in the sample script with the comment **# Configure Permissions** and continues to line 247. The following code fragment first sets permissions to all Surface UEFI settings so that they may be modified by SEMM only, then adds explicit permissions to allow the local user to modify the Surface UEFI password, TPM, and front and rear cameras:
```
202 # Configure Permissions
203 foreach ($uefiV2 IN $surfaceDevices.Values) {
204 # Here we define which "identities" will be allowed to modify which settings
205 # PermissionSignerOwner = The primary SEMM enterprise owner identity
206 # PermissionLocal = The user when booting to the UEFI pre-boot GUI
207 # PermissionSignerUser, PermissionSignerUser1, PermissionSignerUser2 =
208 # Additional user identities created so that the signer owner
209 # can delegate permission control for some settings.
210 $ownerOnly = [Microsoft.Surface.IUefiSetting]::PermissionSignerOwner
211 $ownerAndLocalUser = ([Microsoft.Surface.IUefiSetting]::PermissionSignerOwner -bor [Microsoft.Surface.IUefiSetting]::PermissionLocal)
212
213 # Make all permissions owner only by default
214 foreach ($setting IN $uefiV2.Settings.Values) {
215 $setting.ConfiguredPermissionFlags = $ownerOnly
216 }
217 # Allow the local user to change their own password
218 $uefiV2.SettingsById[501].ConfiguredPermissionFlags = $ownerAndLocalUser
219
220 # Allow the local user to change the state of the TPM
221 $uefiV2.Settings["Trusted Platform Module (TPM)"].ConfiguredPermissionFlags = $ownerAndLocalUser
222
223 # Allow the local user to change the state of the Front and Rear cameras
224 $uefiV2.SettingsById[302].ConfiguredPermissionFlags = $ownerAndLocalUser
225 $uefiV2.SettingsById[304].ConfiguredPermissionFlags = $ownerAndLocalUser
226
227
228 # Create a unique package name based on family and LSV.
229 # We will choose a name that can be parsed by later scripts.
230 $packageName = $uefiV2.SurfaceUefiFamily + "^Permissions^" + $lsv + ".pkg"
231 $fullPackageName = Join-Path -Path $packageRoot -ChildPath $packageName
232
233 # Build and sign the Permission package then save it to a file.
234 $permissionPackageStream = $uefiV2.BuildAndSignPermissionPackage($privateOwnerKey, $password, "", $null, $lsv)
235 $permissionPackage = New-Object System.IO.Filestream($fullPackageName, [System.IO.FileMode]::CreateNew, [System.IO.FileAccess]::Write)
236 $permissionPackageStream.CopyTo($permissionPackage)
237 $permissionPackage.Close()
238 }
210 # Configure Permissions
211 foreach ($uefiV2 IN $surfaceDevices.Values) {
212 if ($uefiV2.SurfaceUefiFamily -eq $Device.Model) {
213 Write-Host "Configuring permissions"
214 Write-Host $Device.Model
215 Write-Host "======================="
216
217 # Here we define which "identities" will be allowed to modify which settings
218 # PermissionSignerOwner = The primary SEMM enterprise owner identity
219 # PermissionLocal = The user when booting to the UEFI pre-boot GUI
220 # PermissionSignerUser, PermissionSignerUser1, PermissionSignerUser2 =
221 # Additional user identities created so that the signer owner
222 # can delegate permission control for some settings.
223 $ownerOnly = [Microsoft.Surface.IUefiSetting]::PermissionSignerOwner
224 $ownerAndLocalUser = ([Microsoft.Surface.IUefiSetting]::PermissionSignerOwner -bor [Microsoft.Surface.IUefiSetting]::PermissionLocal)
225
226 # Make all permissions owner only by default
227 foreach ($setting IN $uefiV2.Settings.Values) {
228 $setting.ConfiguredPermissionFlags = $ownerOnly
229 }
230
231 # Allow the local user to change their own password
232 $uefiV2.SettingsById[501].ConfiguredPermissionFlags = $ownerAndLocalUser
233
234 Write-Host ""
235
236 # Create a unique package name based on family and LSV.
237 # We will choose a name that can be parsed by later scripts.
238 $packageName = $uefiV2.SurfaceUefiFamily + "^Permissions^" + $lsv + ".pkg"
239 $fullPackageName = Join-Path -Path $packageRoot -ChildPath $packageName
240
241 # Build and sign the Permission package then save it to a file.
242 $permissionPackageStream = $uefiV2.BuildAndSignPermissionPackage($privateOwnerKey, $password, "", $null, $lsv)
243 $permissionPackage = New-Object System.IO.Filestream($fullPackageName, [System.IO.FileMode]::CreateNew, [System.IO.FileAccess]::Write)
244 $permissionPackageStream.CopyTo($permissionPackage)
245 $permissionPackage.Close()
246 }
247 }
```
Each **$uefiV2** variable identifies a Surface UEFI setting by setting name or ID, and then configures the permissions to one of the following values:
@ -204,69 +211,169 @@ You can find information about the available settings names and IDs for Surface
### Configure settings
The second region of the script where you will specify the configuration for Surface UEFI is the **Configure Settings** region of the ConfigureSEMM.ps1 script, which configures whether each setting is enabled or disabled. The sample script includes instructions to set all settings to their default values. The script then provides explicit instructions to disable IPv6 for PXE Boot and to leave the Surface UEFI Administrator password unchanged. You can find this region beginning with the **# Configure Settings** comment at line 282 through line 312 in the sample script. The region appears as follows:
The second region of the script where you will specify the configuration for Surface UEFI is the **Configure Settings** region of the ConfigureSEMM.ps1 script, which configures whether each setting is enabled or disabled. The sample script includes instructions to set all settings to their default values. The script then provides explicit instructions to disable IPv6 for PXE Boot and to leave the Surface UEFI Administrator password unchanged. You can find this region beginning with the **# Configure Settings** comment at line 291 through line 335 in the sample script. The region appears as follows:
```
282 # Configure Settings
283 foreach ($uefiV2 IN $surfaceDevices.Values) {
284 # In this demo, we will start by setting every setting to the default factory setting.
285 # You may want to start by doing this in your scripts
286 # so that every setting gets set to a known state.
287 foreach ($setting IN $uefiV2.Settings.Values) {
288 $setting.ConfiguredValue = $setting.DefaultValue
289 }
290
291 # If you want to set something to a different value from the default,
292 # here are examples of how to accomplish this.
293 $uefiV2.Settings["IPv6 for PXE Boot"].ConfiguredValue = "Disabled"
294
295 # If you want to leave the setting unmodified, set it to $null
296 # PowerShell has issues setting things to $null so ClearConfiguredValue()
297 # is supplied to do this explicitly.
298 # Here is an example of leaving the UEFI administrator password as-is,
299 # even after we initially set it to factory default above.
300 $uefiV2.SettingsById[501].ClearConfiguredValue()
301
302 # Create a unique package name based on family and LSV.
303 # We will choose a name that can be parsed by later scripts.
304 $packageName = $uefiV2.SurfaceUefiFamily + "^Settings^" + $lsv + ".pkg"
305 $fullPackageName = Join-Path -Path $packageRoot -ChildPath $packageName
306
307 # Build and sign the Settings package then save it to a file.
308 $settingsPackageStream = $uefiV2.BuildAndSignSecuredSettingsPackage($privateOwnerKey, $password, "", $null, $lsv)
309 $settingsPackage = New-Object System.IO.Filestream($fullPackageName, [System.IO.FileMode]::CreateNew, [System.IO.FileAccess]::Write)
310 $settingsPackageStream.CopyTo($settingsPackage)
311 $settingsPackage.Close()
312 }
291 # Configure Settings
292 foreach ($uefiV2 IN $surfaceDevices.Values) {
293 if ($uefiV2.SurfaceUefiFamily -eq $Device.Model) {
294 Write-Host "Configuring settings"
295 Write-Host $Device.Model
296 Write-Host "===================="
297
298 # In this demo, we will start by setting every setting to the default factory setting.
299 # You may want to start by doing this in your scripts
300 # so that every setting gets set to a known state.
301 foreach ($setting IN $uefiV2.Settings.Values) {
302 $setting.ConfiguredValue = $setting.DefaultValue
303 }
304
305 $EnabledValue = "Enabled"
306 $DisabledValue = "Disabled"
307
308 # If you want to set something to a different value from the default,
309 # here are examples of how to accomplish this.
310 # This disables IPv6 PXE boot by name:
311 $uefiV2.Settings["IPv6 for PXE Boot"].ConfiguredValue = $DisabledValue
312
313 # This disables IPv6 PXE Boot by ID:
314 $uefiV2.SettingsById[400].ConfiguredValue = $DisabledValue
315
316 Write-Host ""
317
318 # If you want to leave the setting unmodified, set it to $null
319 # PowerShell has issues setting things to $null so ClearConfiguredValue()
320 # is supplied to do this explicitly.
321 # Here is an example of leaving the UEFI administrator password as-is,
322 # even after we initially set it to factory default above.
323 $uefiV2.SettingsById[501].ClearConfiguredValue()
324
325 # Create a unique package name based on family and LSV.
326 # We will choose a name that can be parsed by later scripts.
327 $packageName = $uefiV2.SurfaceUefiFamily + "^Settings^" + $lsv + ".pkg"
328 $fullPackageName = Join-Path -Path $packageRoot -ChildPath $packageName
329
330 # Build and sign the Settings package then save it to a file.
331 $settingsPackageStream = $uefiV2.BuildAndSignSecuredSettingsPackage($privateOwnerKey, $password, "", $null, $lsv)
332 $settingsPackage = New-Object System.IO.Filestream($fullPackageName, [System.IO.FileMode]::CreateNew, [System.IO.FileAccess]::Write)
333 $settingsPackageStream.CopyTo($settingsPackage)
334 $settingsPackage.Close()
335 }
```
Like the permissions set in the **Configure Permissions** section of the script, the configuration of each Surface UEFI setting is performed by defining the **$uefiV2** variable. For each line defining the **$uefiV2** variable, a Surface UEFI setting is identified by setting name or ID and the configured value is set to **Enabled** or **Disabled**.
If you do not want to alter the configuration of a Surface UEFI setting, for example to ensure that the Surface UEFI administrator password is not cleared by the action of resetting all Surface UEFI settings to their default, you can use **ClearConfiguredValue()** to enforce that this setting will not be altered. In the sample script, this is used on line 300 to prevent the clearing of the Surface UEFI Administrator password, identified in the sample script by its setting ID, **501**.
If you do not want to alter the configuration of a Surface UEFI setting, for example to ensure that the Surface UEFI administrator password is not cleared by the action of resetting all Surface UEFI settings to their default, you can use **ClearConfiguredValue()** to enforce that this setting will not be altered. In the sample script, this is used on line 323 to prevent the clearing of the Surface UEFI Administrator password, identified in the sample script by its setting ID, **501**.
You can find information about the available settings names and IDs for Surface UEFI in the [Settings Names and IDs](#settings-names-and-ids) section later in this article.
### Settings registry key
To identify enrolled systems for Configuration Manager, the ConfigureSEMM.ps1 script writes a registry key that can be used to identify enrolled systems as having been installed with the SEMM configuration script. This key can be found at the following location:
To identify enrolled systems for Configuration Manager, the ConfigureSEMM.ps1 script writes a registry keys that can be used to identify enrolled systems as having been installed with the SEMM configuration script. These keys can be found at the following location:
`HKLM\SOFTWARE\Microsoft\Surface\SEMM\Enabled_Version1000`
`HKLM\SOFTWARE\Microsoft\Surface\SEMM`
The following code fragment, found on lines 352-363, is used to write this registry key:
The following code fragment, found on lines 380-477, is used to write these registry keys:
```
352 $SurfaceRegKey = "HKLM:\SOFTWARE\Microsoft\Surface\SEMM"
353 New-RegKey $SurfaceRegKey
354 $SurfaceRegValue = Get-ItemProperty $SurfaceRegKey Enabled_Version1000 -ErrorAction SilentlyContinue
355
356 If ($SurfaceRegValue -eq $null)
357 {
358 New-ItemProperty -Path $SurfaceRegKey -Name Enabled_Version1000 -PropertyType String -Value 1 | Out-Null
359 }
360 Else
361 {
362 Set-ItemProperty -Path $SurfaceRegKey -Name Enabled_Version1000 -Value 1
363 }
380 # For SCCM or other management solutions that wish to know what version is applied, tattoo the LSV and current DateTime (in UTC) to the registry:
381 $UTCDate = (Get-Date).ToUniversalTime().ToString()
382 $certIssuer = $certPrint.Issuer
383 $certSubject = $certPrint.Subject
384
385 $SurfaceRegKey = "HKLM:\SOFTWARE\Microsoft\Surface\SEMM"
386 New-RegKey $SurfaceRegKey
387 $LSVRegValue = Get-ItemProperty $SurfaceRegKey LSV -ErrorAction SilentlyContinue
388 $DateTimeRegValue = Get-ItemProperty $SurfaceRegKey LastConfiguredUTC -ErrorAction SilentlyContinue
389 $OwnershipSessionIdRegValue = Get-ItemProperty $SurfaceRegKey OwnershipSessionId -ErrorAction SilentlyContinue
390 $PermissionSessionIdRegValue = Get-ItemProperty $SurfaceRegKey PermissionSessionId -ErrorAction SilentlyContinue
391 $SettingsSessionIdRegValue = Get-ItemProperty $SurfaceRegKey SettingsSessionId -ErrorAction SilentlyContinue
392 $IsResetRegValue = Get-ItemProperty $SurfaceRegKey IsReset -ErrorAction SilentlyContinue
393 $certUsedRegValue = Get-ItemProperty $SurfaceRegKey CertName -ErrorAction SilentlyContinue
394 $certIssuerRegValue = Get-ItemProperty $SurfaceRegKey CertIssuer -ErrorAction SilentlyContinue
395 $certSubjectRegValue = Get-ItemProperty $SurfaceRegKey CertSubject -ErrorAction SilentlyContinue
396
397
398 If ($LSVRegValue -eq $null)
399 {
400 New-ItemProperty -Path $SurfaceRegKey -Name LSV -PropertyType DWORD -Value $lsv | Out-Null
401 }
402 Else
403 {
404 Set-ItemProperty -Path $SurfaceRegKey -Name LSV -Value $lsv
405 }
406
407 If ($DateTimeRegValue -eq $null)
408 {
409 New-ItemProperty -Path $SurfaceRegKey -Name LastConfiguredUTC -PropertyType String -Value $UTCDate | Out-Null
410 }
411 Else
412 {
413 Set-ItemProperty -Path $SurfaceRegKey -Name LastConfiguredUTC -Value $UTCDate
414 }
415
416 If ($OwnershipSessionIdRegValue -eq $null)
417 {
418 New-ItemProperty -Path $SurfaceRegKey -Name OwnershipSessionId -PropertyType String -Value $ownerSessionIdValue | Out-Null
419 }
420 Else
421 {
422 Set-ItemProperty -Path $SurfaceRegKey -Name OwnershipSessionId -Value $ownerSessionIdValue
423 }
424
425 If ($PermissionSessionIdRegValue -eq $null)
426 {
427 New-ItemProperty -Path $SurfaceRegKey -Name PermissionSessionId -PropertyType String -Value $permissionSessionIdValue | Out-Null
428 }
429 Else
430 {
431 Set-ItemProperty -Path $SurfaceRegKey -Name PermissionSessionId -Value $permissionSessionIdValue
432 }
433
434 If ($SettingsSessionIdRegValue -eq $null)
435 {
436 New-ItemProperty -Path $SurfaceRegKey -Name SettingsSessionId -PropertyType String -Value $settingsSessionIdValue | Out-Null
437 }
438 Else
439 {
440 Set-ItemProperty -Path $SurfaceRegKey -Name SettingsSessionId -Value $settingsSessionIdValue
441 }
442
443 If ($IsResetRegValue -eq $null)
444 {
445 New-ItemProperty -Path $SurfaceRegKey -Name IsReset -PropertyType DWORD -Value 0 | Out-Null
446 }
447 Else
448 {
449 Set-ItemProperty -Path $SurfaceRegKey -Name IsReset -Value 0
450 }
451
452 If ($certUsedRegValue -eq $null)
453 {
454 New-ItemProperty -Path $SurfaceRegKey -Name CertName -PropertyType String -Value $certName | Out-Null
455 }
456 Else
457 {
458 Set-ItemProperty -Path $SurfaceRegKey -Name CertName -Value $certName
459 }
460
461 If ($certIssuerRegValue -eq $null)
462 {
463 New-ItemProperty -Path $SurfaceRegKey -Name CertIssuer -PropertyType String -Value $certIssuer | Out-Null
464 }
465 Else
466 {
467 Set-ItemProperty -Path $SurfaceRegKey -Name CertIssuer -Value $certIssuer
468 }
469
470 If ($certSubjectRegValue -eq $null)
471 {
472 New-ItemProperty -Path $SurfaceRegKey -Name CertSubject -PropertyType String -Value $certSubject | Out-Null
473 }
474 Else
475 {
476 Set-ItemProperty -Path $SurfaceRegKey -Name CertSubject -Value $certSubject
477 }
```
### Settings names and IDs