├── Intune Scripts ├── BIOS Settings │ ├── Dell_BIOS_Baseline.ps1 │ ├── Dell_BIOS_Password.ps1 │ ├── Dell_BIOS_Setting.ps1 │ ├── Dell_BIOS_Boot_Order.ps1 │ └── Dell_BIOS_Persistence.ps1 ├── System Information │ ├── Intune_Retreive_CPUInfo.ps1 │ ├── Intune_Retreive_serviceTag.ps1 │ ├── SystemInformation_Readme.txt │ ├── Intune_Retreive_BIOS_version.ps1 │ ├── Intune_Retreive_Manufacturer.ps1 │ └── Dell_Warranty_Bulk.ps1 ├── TPM Activation and Security │ ├── Dell_BIOS_TPM_Pre_Reboot.ps1 │ └── Dell_BIOS_TPM_Post_Reboot.ps1 ├── Custom Compliance │ ├── Intune_Compliance_HDD_Health.json │ ├── Intune_Compliance_Memory_Health.json │ ├── Intune_Compliance_Battery_Health.json │ ├── Intune_Compliance_Chassis_Intrusion.json │ ├── Intune_Compliance_Warranty_expire.json │ ├── Intune_Compliance_Sensor_Battery_Health.ps1 │ ├── CustomCompliance_Readme.txt │ ├── Intune_Compliance_Sensor_DCM_Warranty_expire.ps1 │ ├── Intune_Compliance_Sensor_WMI_HDD_Health.ps1 │ ├── Intune_Compliance_Sensor_WMI_Chassis_Intrusion.ps1 │ └── Intune_Compliance_Sensor_Memory_Health.ps1 ├── Proactive Remediation │ ├── ProactiveRemediation_Readme.txt │ ├── Intune_Detection_BIOS_AdminPW_Setting.ps1 │ ├── Intune_Detection_BIOS_Thermalmode_Setting.ps1 │ ├── Intune_Detection_BIOS_AdminPW_Change.ps1 │ ├── Intune_Remediation_BIOS_Thermalmode_Setting.ps1 │ └── Intune_Remediation_BIOS_AdminPW_Setting.ps1 ├── EnterpriseAppDeployment │ └── Readme.md ├── UEFI Variable Settings │ ├── Dell_SetForcedNetworkFlag.ps1 │ └── Dell_GetForcedNetworkFlag.ps1 └── Update │ ├── Dell_Download_Driver_Files.ps1 │ └── Dell_Install_Driver_Files.ps1 ├── README.md └── LICENSE /Intune Scripts/BIOS Settings/Dell_BIOS_Baseline.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/BIOS Settings/Dell_BIOS_Baseline.ps1 -------------------------------------------------------------------------------- /Intune Scripts/BIOS Settings/Dell_BIOS_Password.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/BIOS Settings/Dell_BIOS_Password.ps1 -------------------------------------------------------------------------------- /Intune Scripts/BIOS Settings/Dell_BIOS_Setting.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/BIOS Settings/Dell_BIOS_Setting.ps1 -------------------------------------------------------------------------------- /Intune Scripts/BIOS Settings/Dell_BIOS_Boot_Order.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/BIOS Settings/Dell_BIOS_Boot_Order.ps1 -------------------------------------------------------------------------------- /Intune Scripts/BIOS Settings/Dell_BIOS_Persistence.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/BIOS Settings/Dell_BIOS_Persistence.ps1 -------------------------------------------------------------------------------- /Intune Scripts/System Information/Intune_Retreive_CPUInfo.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/System Information/Intune_Retreive_CPUInfo.ps1 -------------------------------------------------------------------------------- /Intune Scripts/System Information/Intune_Retreive_serviceTag.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/System Information/Intune_Retreive_serviceTag.ps1 -------------------------------------------------------------------------------- /Intune Scripts/TPM Activation and Security/Dell_BIOS_TPM_Pre_Reboot.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/TPM Activation and Security/Dell_BIOS_TPM_Pre_Reboot.ps1 -------------------------------------------------------------------------------- /Intune Scripts/TPM Activation and Security/Dell_BIOS_TPM_Post_Reboot.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dell/Endpoint-Management-Script-Library/HEAD/Intune Scripts/TPM Activation and Security/Dell_BIOS_TPM_Post_Reboot.ps1 -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_HDD_Health.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rules":[ 3 | { 4 | "SettingName":"HealthStatus", 5 | "Operator":"isEquals", 6 | "DataType":"String", 7 | "Operand":"Healthy", 8 | "MoreInfoUrl":"https://www.dell.com/support/", 9 | "RemediationStrings":[ 10 | { 11 | "Language":"en_US", 12 | "Title":"Hard Drive of your device is not healthy", 13 | "Description": "Please contact Administrator" 14 | } 15 | ] 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Memory_Health.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rules":[ 3 | { 4 | "SettingName":"HealthStatus", 5 | "Operator":"isEquals", 6 | "DataType":"String", 7 | "Operand":"Healthy", 8 | "MoreInfoUrl":"https://www.dell.com/support/manuals/en-us/command-monitor/dcm_rg_10.9.1/dcim_memory?guid=guid-517eec82-6f54-4317-8826-bfcf77c42f7e&lang=en-us", 9 | "RemediationStrings":[ 10 | { 11 | "Language":"en_US", 12 | "Title":"Memory of your device is not healthy", 13 | "Description": "Please contact Administrator" 14 | } 15 | ] 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Battery_Health.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rules":[ 3 | { 4 | "SettingName":"BatteryHealth", 5 | "Operator":"isEquals", 6 | "DataType":"String", 7 | "Operand":"OK", 8 | "MoreInfoUrl":"https://www.dell.com/support/manuals/en-us/command-monitor/dellcommandmonitor_rg_10.6/dcim_battery?guid=guid-0176acfb-3ff2-4895-9521-33c9bc948f0b&lang=en-us", 9 | "RemediationStrings":[ 10 | { 11 | "Language":"en_US", 12 | "Title":"Battery of your device is not healthy", 13 | "Description": "Battery healty check link for more informations or using Dell Support Assist for a Hardware Scan" 14 | } 15 | ] 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Chassis_Intrusion.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rules":[ 3 | { 4 | "SettingName":"IntrusionSetting", 5 | "Operator":"IsEquals", 6 | "DataType":"Int64", 7 | "Operand":"3", 8 | "MoreInfoUrl":"https://www.dell.com/support/", 9 | "RemediationStrings":[ 10 | { 11 | "Language":"en_US", 12 | "Title":"Chassis Intrusion detection is not enabled", 13 | "Description": "Please contact Administrator to change BIOS setting on your device" 14 | } 15 | ] 16 | }, 17 | { 18 | "SettingName":"IntrusionStatus", 19 | "Operator":"IsEquals", 20 | "DataType":"Int64", 21 | "Operand":"3", 22 | "MoreInfoUrl":"https://www.dell.com/support/", 23 | "RemediationStrings":[ 24 | { 25 | "Language": "en_US", 26 | "Title": "Chassis Intrusion Alert", 27 | "Description": "Please contact Administrator" 28 | } 29 | ] 30 | } 31 | 32 | ] 33 | } -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Warranty_expire.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rules":[ 3 | { 4 | "SettingName":"Support", 5 | "Operator":"GreaterThan", 6 | "DataType":"Int64", 7 | "Operand":"0", 8 | "MoreInfoUrl":"https://www.dell.com/support/", 9 | "RemediationStrings":[ 10 | { 11 | "Language":"en_US", 12 | "Title":"This Device have no Hardware support", 13 | "Description": "Support Contract has ended, please request a new device" 14 | } 15 | ] 16 | }, 17 | { 18 | "SettingName":"Last30Days", 19 | "Operator":"GreaterThan", 20 | "DataType":"Int64", 21 | "Operand":"0", 22 | "MoreInfoUrl":"https://www.dell.com/support/", 23 | "RemediationStrings":[ 24 | { 25 | "Language":"en_US", 26 | "Title":"Hardware support for this device will ending soon", 27 | "Description": "Support Contract will ending, please request a new device" 28 | } 29 | ] 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /Intune Scripts/System Information/SystemInformation_Readme.txt: -------------------------------------------------------------------------------- 1 | The scripts in this folder must be run from the Intune Proactive Remediations. The scripts are only for detection and do not contain any remediation script. 2 | The folder contains the following scripts: 3 | 4 | 1. Intune_Retreive_BIOS_version.ps1: 5 | This script uses the DCIM_BIOSElement class to retrieve the BIOS version in JSON format. An example of the BIOS version retrieved in JSON format is- {"Version":"1.2.2"} 6 | 7 | 2. Intune_Retreive_Manufacturer.ps1: 8 | This script uses the DCIM_Chassis class to retrieve the manufacturer’s information in JSON format. An example of the manufacturer’s details retrieved in JSON format is- {"Manufacturer":"Dell Inc."} 9 | 10 | 3. Intune_Retreive_serviceTag.ps1: 11 | This script uses the DCIM_Chassis class to retrieve the Service Tag of the system in JSON format. An example of the Service Tag retrieved in JSON format is- {"ServiceTag":"8GBK2A4"} 12 | 13 | 4. Intune_Retreive_CPUInfo.ps1: 14 | This script uses the DCIM_Processor class to retrieve the CPU information of the system in JSON format. An example of the CPU information retrieved in JSON format is- {"UniqueID":"PortProcessorObj", 15 | "ProcessorName":"Processor 1 : Genuine Intel(R) CPU 0000 @ 2.60GHz Stepping 0","NumberOfEnabledCores":8,"SystemName":"nb:W47Y0WN","CPUStatus":"CPU Enabled", 16 | "CurrentClockSpeed":4059,"RequestedState":"Not Applicable","PrimaryStatus":"OK","Family":1,"EnabledState":"Enabled","TransitioningToState":"Not Applicable", 17 | "OperationalStatus":"OK","HealthState":"OK","Stepping":"","ExternalBusClockSpeed":100,"EnabledDefault":"Enabled","UpgradeMethod":1,"MaxClockSpeed":3100} 18 | 19 | 20 | -------------------------------------------------------------------------------- /Intune Scripts/Proactive Remediation/ProactiveRemediation_Readme.txt: -------------------------------------------------------------------------------- 1 | The scripts in this folder must be run from the Intune Proactive Remediations. It requires both the detection script and remediation script. 2 | The folder contains the following scripts: 3 | 4 | 1. Intune_Detection_BIOS_AdminPW_Setting.ps1: 5 | The detection script checks if the BIOS admin password is set on the system, followed by the remediation script if the BIOS password is not set. 6 | 7 | 2. Intune_Detection_BIOS_AdminPW_Change.ps1: 8 | The detection script checks if the BIOS Admin password is older than 180 days and must be changed. 9 | Note: This script must be used only after the remediation script for setting the BIOS password (Intune_Remediation_BIOS_AdminPW_Setting.ps1) is run, as it looks for the Update parameter from the registry key. 10 | Note: 180 days is the default time interval and can be changed as per the requirements. 11 | 12 | 3. Intune_Remediation_BIOS_AdminPW_Setting.ps1: 13 | The remediation script sets the new BIOS admin password if the password is not already set and creates a registry key- HKLM:\SOFTWARE\Dell\BIOS. 14 | Also, it updates the password if the existing password from the registry key is older than the time interval set. 15 | 16 | 4. Intune_5_Detection_BIOS_Thermalmode_Setting.ps1: 17 | The detection script checks if the client BIOS Thermal Management setting is set as Quiet, using Dell | Command Monitor. 18 | Note: This script needs a client installation of Dell | Command Monitor. 19 | 20 | 5. Intune_5_Remediation_BIOS_Thermalmode_Setting.ps1: 21 | The remediation script sets the BIOS Thermal Management setting as Quiet if not already set, using Dell | Command Monitor. 22 | Note: This script needs a client installation of Dell | Command Monitor. 23 | -------------------------------------------------------------------------------- /Intune Scripts/System Information/Intune_Retreive_BIOS_version.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Bulusu, SaiSameerKrishna 3 | _version_ = 1.0.0 4 | 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 24 | 25 | #> 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell script retrieves the BIOS version of the system. 30 | IMPORTANT: This script need a client installation of Dell Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 31 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script 32 | IMPORTANT: This script does not reboot the system to apply or query system. 33 | .DESCRIPTION 34 | This Powershell script uses WMI call to retrieve the BIOS version in JSON format. 35 | .EXAMPLE 36 | An example of the BIOS version retrived in JSON format: 37 | {"Version":"1.2.2"} 38 | #> 39 | 40 | $BiosVersion= Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_BIOSElement | Select -ExpandProperty Version 41 | 42 | if($BiosVersion -ne $null) 43 | { 44 | $hash = @{ Version = $BiosVersion } 45 | 46 | return $hash | ConvertTo-Json -Compress 47 | } 48 | else 49 | { 50 | exit 1 51 | } 52 | -------------------------------------------------------------------------------- /Intune Scripts/System Information/Intune_Retreive_Manufacturer.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Bulusu, SaiSameerKrishna 3 | _version_ = 1.0.0 4 | 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 24 | 25 | #> 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell script retrieves the manufacturer of the system. 30 | IMPORTANT: This script need a client installation of Dell Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 31 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script 32 | IMPORTANT: This script does not reboot the system to apply or query system. 33 | .DESCRIPTION 34 | This Powershell script uses WMI call to retrieve the manufacturer information in JSON format. 35 | .EXAMPLE 36 | An example of the manufacturer info retrived in JSON format: 37 | {"Manufacturer":"Dell Inc."} 38 | #> 39 | 40 | $Manufacturer= Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_Chassis | Select -ExpandProperty Manufacturer 41 | 42 | if($Manufacturer -ne $null) 43 | { 44 | $hash = @{ Manufacturer = $Manufacturer } 45 | 46 | return $hash | ConvertTo-Json -Compress 47 | } 48 | else 49 | { 50 | exit 1 51 | } -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Sensor_Battery_Health.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.0 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 24 | 25 | #> 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell is for custom compliance scans and checking is mobile battery healthy. 30 | IMPORTANT: This script need a client installation of Dell Command Monitor first. https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 31 | IMPORTANT: This script does not reboot the system to apply or query system. 32 | .DESCRIPTION 33 | Powershell using Dell Command Monitor to made WMI request of mobile battery Health status on the device. This script need to be upload in Intune Compliance / Script and need a JSON file additional for reporting this value. 34 | NOTE: This script is limited to laptops with a single battery. 35 | NOTE: This script verifies if the system is compliant or not as per the rules mentioned in the JSON file. 36 | #> 37 | 38 | #checking WMI status with Dell Command Monitor and switch value to a useful text. 39 | $BatteryHealth = Switch (Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_Battery | Select -ExpandProperty HealthState) 40 | { 41 | 0 {"Unknown"} 42 | 5 {"OK"} 43 | 10 {"Degraded/Warning"} 44 | 15 {"Minor failure"} 45 | 20 {"Major failure"} 46 | 25 {"Critical failure"} 47 | 30 {"Non-recoverable error"} 48 | } 49 | 50 | #prepare variable for Intune 51 | $hash = @{ BatteryHealth = $BatteryHealth } 52 | 53 | #convert variable to JSON format 54 | return $hash | ConvertTo-Json -Compress 55 | 56 | -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/CustomCompliance_Readme.txt: -------------------------------------------------------------------------------- 1 | The scripts in this folder need to be uploaded with JSON file in the Intune Compliance policies and scripts. 2 | The folder contains the following scripts: 3 | 4 | 1. Intune_Compliance_Sensor_Battery_Health.ps1: 5 | This Powershell script uses Dell Command | Monitor to make WMI request of mobile battery health status on the device. This script must be uploaded in Intune Compliance or Script and needs an additional JSON file for reporting. 6 | This script is limited to laptops with a single battery. It verifies if the system is compliant or not as per the rules that are mentioned in the JSON file (Intune_Compliance_Battery_Health.json). 7 | 8 | 2. Intune_Compliance_Sensor_DCM_Warranty_expire.ps1 9 | This Powershell script uses Dell Command | Monitor to check the support contract time of the device. This script must be uploaded in Intune Compliance or Script and needs an additional JSON file for reporting. 10 | This script looks for the last ending warranty and checks if the warranty is active. It does not look for multiple warranties with different expiry dates. 11 | This script verifies if the system is compliant or not as per the rules that are mentioned in the JSON file (Intune_Compliance_Battery_Health.json). 12 | 13 | 3. Intune_Compliance_Sensor_WMI_Chassis_Intrusion.ps1 14 | This Powershell script uses WMI to check the BIOS settings - chassisintrusion and ChassisIntrusionStatus. The script must be uploaded in Intune Compliance or Script and needs an additional JSON file for reporting. 15 | It verifies if the system is compliant or not as per the rules that are mentioned in the JSON file (Intune_Compliance_Chassis_Intrusion.json). 16 | It checks if the BIOS setting Intrusion detection is Silentenabled currently and Intrusion Status is Door Closed. 17 | 18 | 4. Intune_Compliance_Sensor_WMI_HDD_Health.ps1 19 | This Powershell script uses WMI to check the Hard Drive health status on the device. The script must be uploaded in Intune Compliance or Script and needs an additional JSON file for reporting. 20 | It verifies if the system is compliant or not as per the rules that are mentioned in the JSON file (Intune_Compliance_HDD_Health.json). 21 | 22 | 5. Intune_Compliance_Sensor_Memory_Health.ps1 23 | This Powershell script uses Dell Command | Monitor to make WMI request of memory health status on the device. This script must be uploaded in Intune Compliance or Script and needs an additional JSON file for reporting. 24 | It verifies if the system is compliant or not as per the rules that are mentioned in the JSON file (Intune_Compliance_Memory_Health.json). -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Sensor_DCM_Warranty_expire.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.0 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 24 | 25 | #> 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell is for custom compliance scans and is checking the support contract time of this device by Dell Command Monitor (DCM) 30 | IMPORTANT: This script need a client installation of Dell Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 31 | IMPORTANT: This script does not reboot the system to apply or query system. 32 | .DESCRIPTION 33 | Powershell using Dell Command Monitor WMI to check the support contract time of the device. This script need to be upload in Intune Compliance / Script and need a JSON file additional for reporting this value. 34 | NOTE: This script looks only for the last ending warranty and checks if this warranty is currently active. This script does not look for multiple warranties with different expiry dates. 35 | NOTE: This script verifies if the system is compliant or not as per the rules mentioned in the JSON file. 36 | #> 37 | 38 | 39 | 40 | # prepare Dell Warranty date for compare with actual date 41 | $WarrantyEnd = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_AssetWarrantyInformation | Sort-Object WarrantyEndDate -Descending | select -ExpandProperty WarrantyEndDate 42 | $WarrantyEndSelect = $WarrantyEnd[0] -split "," 43 | $WarrantyDate = $WarrantyEndSelect -split " " 44 | [datetime]$FinalDate = $WarrantyDate.GetValue(0) 45 | 46 | # Check availible support days 47 | $Today = Get-Date 48 | $Duration = New-TimeSpan -Start $Today -End $FinalDate 49 | $last30Days = New-TimeSpan -Start $Today -End $FinalDate.AddDays(-30) 50 | 51 | #prepare variable for Intune 52 | $hash = @{ Support = $Duration.Days; Last30Days = $last30Days.Days } 53 | 54 | #convert variable to JSON format 55 | return $hash | ConvertTo-Json -Compress -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Sensor_WMI_HDD_Health.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Mahesh AC 3 | _version_ = 1.0.0 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 24 | #> 25 | <# 26 | .Synopsis 27 | This PowerShell is for custom compliance scans and is checking Heath Status of the Hard Drive in the Device. 28 | 29 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script. 30 | IMPORTANT: This script does not reboot the system to apply or query system. 31 | .DESCRIPTION 32 | Powershell script using WMI to check the Health Status of the Hard drive. This script needs to be uploaded in Intune Compliance / Script and needs a JSON file additional for reporting this value. 33 | NOTE: This script verifies if the system is compliant or not as per the rules mentioned in the JSON file. 34 | #> 35 | 36 | 37 | #checking the Health Status of the Hard Drive in the device through WMI 38 | $health = Get-PhysicalDisk | select FriendlyName,MediaType,HealthStatus 39 | $errorcheck = 0 40 | 41 | if($health -eq $null) 42 | { 43 | write-host " No HDD's Found in the System - System Does not have any Hard Drives" 44 | exit 1 45 | } 46 | else 47 | { 48 | $instances = $health.FriendlyName 49 | Write-Host "$instances" 50 | 51 | foreach($x in 0..($instances.count - 1)) 52 | { 53 | 54 | if ($health[$x].HealthStatus -eq "Healthy") 55 | 56 | { 57 | Write-host "PASS- HDD Helath Status is Good for",$health[$x].FriendlyName 58 | } 59 | else 60 | { 61 | Write-host "FAIL- HDD Heath Status is BAD for",$health[$x].FriendlyName 62 | $errorcheck=1 63 | } 64 | } 65 | } 66 | 67 | if ($errorcheck -eq 0) 68 | { 69 | 70 | Write-Host "Overall Status is Good" 71 | } 72 | else 73 | { 74 | Write-Host "There is failure with one of the Hard Drive" 75 | 76 | } 77 | 78 | $HDDHealth = switch($errorcheck) 79 | { 80 | 0 {"Healthy"} 81 | 1 {"Not Healthy"} 82 | } 83 | 84 | #prepare variable for Intune 85 | $hash = @{ HealthStatus = $HDDHealth } 86 | 87 | #convert variable to JSON format 88 | return $hash | ConvertTo-Json -Compress 89 | 90 | -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Sensor_WMI_Chassis_Intrusion.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.1 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 1.0.1 The BIOS setting "chassis intrusion" is retrieved using DCM -"DCIM_BIOSEnumeration" class instead of WMI Namespace root/dcim/sysman/biosattributes and class "EnumerationAttribute". 24 | 25 | 26 | #> 27 | 28 | <# 29 | .Synopsis 30 | This PowerShell is for custom compliance scans and is checking this device of BIOS setting Intrusion detection was enabled and Intrusion Status. 31 | IMPORTANT: This script need a client installation of Dell Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 32 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script. 33 | IMPORTANT: This script does not reboot the system to apply or query system. 34 | .DESCRIPTION 35 | Powershell using WMI to check the BIOS value of chassis intrusion and ChassisIntrusionStatus. This script needs to be uploaded in Intune Compliance / Script and needs a JSON file additional for reporting this value. 36 | NOTE: This script verifies if the system is compliant or not as per the rules mentioned in the JSON file. 37 | #> 38 | 39 | # check chassis intrusion with WMI 40 | $CheckChassisSetting = Get-CimInstance -Namespace root/dcim/sysman -ClassName DCIM_BIOSEnumeration -Filter "AttributeName like 'Chassis Intrusion'" | select -ExpandProperty CurrentValue 41 | $CheckIntrusion = Get-CimInstance -Namespace root/dcim/sysman -ClassName DCIM_BIOSEnumeration -Filter "AttributeName like 'Chassis Intrusion Status'" | select -ExpandProperty CurrentValue 42 | 43 | <# 44 | ChasIntrusion 45 | 1 == Disabled = no logging 46 | 2 == Enabled = logging with post boot alert 47 | 3 == SilentEnable =logging without post boot alert 48 | 49 | 50 | 51 | Chassis Intrusion Status 52 | 53 | 1 = Tripped 54 | 2 = Door open 55 | 3 = Door closed 56 | 4 = Trip reset 57 | 58 | #> 59 | 60 | #prepare variable for Intune 61 | $hash = @{ IntrusionSetting = $CheckChassisSetting; IntrusionStatus = $CheckIntrusion } 62 | 63 | #convert variable to JSON format 64 | return $hash | ConvertTo-Json -Compress -------------------------------------------------------------------------------- /Intune Scripts/Custom Compliance/Intune_Compliance_Sensor_Memory_Health.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Mahesh AC 3 | _version_ = 1.0.0 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 inital version 23 | 24 | #> 25 | 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell is for custom compliance scans and is checking Heath Status of the Memory in the Device. 30 | IMPORTANT: This script need a client installation of Dell Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 31 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script. 32 | IMPORTANT: This script does not reboot the system to apply or query system. 33 | .DESCRIPTION 34 | Powershell script using Dell Command Monitor to check the Health Status of the Memory. This script needs to be uploaded in Intune Compliance / Script and needs a JSON file additional for reporting this value. 35 | NOTE: This script verifies if the system is compliant or not as per the rules mentioned in the JSON file. 36 | #> 37 | 38 | 39 | #checking the Health Status of the Memory in the device through WMI 40 | $health = Get-CimInstance -Namespace root/DCIM/SYSMAN -ClassName dcim_memory | select ElementName,DeviceID,HealthState 41 | $errorcheck = 0 42 | 43 | if($health -eq $null) 44 | { 45 | write-host " Memory Detection is failed - System Does not have any RAMs/DCM is Not Installed" 46 | exit 1 47 | } 48 | else 49 | { 50 | $instances = $health.ElementName 51 | foreach($x in 0..($instances.count - 1)) 52 | { 53 | if ($health.HealthState[$x] -eq 5) 54 | { 55 | Write-host "PASS- Memory Health State is Good for",$health.ElementName[$x] 56 | } 57 | else 58 | { 59 | Write-host "FAIL- Memory Health State is BAD for",$health.ElementName[$x] 60 | $errorcheck=1 61 | } 62 | } 63 | } 64 | if ($errorcheck -eq 0) 65 | { 66 | 67 | Write-Host "Overall Status is Good" 68 | } 69 | else 70 | { 71 | Write-Host "There is failure with one of the RAMS" 72 | 73 | } 74 | 75 | $MemoryHealth = switch($errorcheck) 76 | { 77 | 0 {"Healthy"} 78 | 1 {"Not Healthy"} 79 | } 80 | 81 | #prepare variable for Intune 82 | $hash = @{ HealthStatus = $MemoryHealth } 83 | 84 | #convert variable to JSON format 85 | return $hash | ConvertTo-Json -Compress 86 | 87 | -------------------------------------------------------------------------------- /Intune Scripts/Proactive Remediation/Intune_Detection_BIOS_AdminPW_Setting.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <# 21 | .Synopsis 22 | This PowerShell script checks if BIOS AdminPW is set on this machine using WMI 23 | IMPORTANT: This script needs a client which supports the WMI Namespace "root/dcim/sysman/wmisecurity" and the WMI class "PasswordObject". 24 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script. 25 | IMPORTANT: This script does not reboot the system to apply or query system. 26 | 27 | .DESCRIPTION 28 | PowerShell to import as Dection Script for Microsoft Endpoint Manager. This Script need to be imported in Reports/Endpoint Analytics/Proactive remediation. This File is for detection only and need a seperate script for remediation additional. 29 | NOTE: The pre-remediation detection script output is available in Intune reports in the "Pre-remediation detection output" column. 30 | NOTE: The post-remediation detection script output is available in Intune reports in the "Post-remediation detection output" column. 31 | NOTE: The remediation script log message are available on the endpoint at this path: "C:\Temp\BIOS_Profile.txt" 32 | #> 33 | 34 | try{ 35 | 36 | # Check BIOS AttributName AdminPW is set 37 | $BIOSAdminPW = Get-CimInstance -Namespace root/dcim/sysman/wmisecurity -ClassName PasswordObject -Filter "NameId='Admin'" | Select-Object -ExpandProperty IsPasswordSet 38 | 39 | if($BIOSAdminPW -eq $null) 40 | { 41 | Write-Error -Category ResourceUnavailable -CategoryTargetName "root/dcim/sysman/wmisecurity" -CategoryTargetType "PasswordObject" -Message "Unable to get the 'Admin' object in class 'PasswordObject' in the Namespace 'root/dcim/sysman/wmisecurity'" 42 | exit 1 43 | } 44 | elseif ($BIOSAdminPW -match "1") 45 | { 46 | write-host "BIOS Admin password is set on this machine." 47 | exit 0 48 | } 49 | else 50 | { 51 | Write-Host "No BIOS Admin PW is set on this machine. Running the remediation script to set the password.." 52 | exit 1 53 | } 54 | } 55 | catch 56 | { 57 | $errMsg = $_.Exception.Message 58 | write-Error $errMsg 59 | exit 1 60 | } -------------------------------------------------------------------------------- /Intune Scripts/Proactive Remediation/Intune_Detection_BIOS_Thermalmode_Setting.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.1 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 Initial version 23 | 1.0.1 Replacing WMI query with Dell | Command Monitor query to get the BIOS Thermal Management setting. 24 | 25 | #> 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell script checks if the client BIOS Thermal Management is set to "Quiet" using Dell | Command Monitor. 30 | IMPORTANT: This script needs a client installation of Dell | Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 31 | IMPORTANT: This script does not reboot the system to apply or query any settings. 32 | .DESCRIPTION 33 | This script needs to be imported in Reports/Endpoint Analytics/Proactive remediation. This File is for detection only and needs a seperate script for remediation. 34 | NOTE: The pre-remediation detection script output is available in Intune reports in the "Pre-remediation detection output" column. 35 | NOTE: The post-remediation detection script output is available in Intune reports in the "Post-remediation detection output" column. 36 | #> 37 | 38 | try 39 | { 40 | # Check BIOS AttributName ThermalSetting is Value Quiet 41 | $BIOSThermalMode= Switch ( Get-CimInstance -Namespace root/dcim/sysman -ClassName DCIM_ThermalInformation -Filter "AttributeName='Thermal Mode'"| Select-Object -ExpandProperty CurrentValue) 42 | { 43 | 0 {"Optimized"} 44 | 1 {"Cool"} 45 | 2 {"Quiet"} 46 | 3 {"Performance"} 47 | } 48 | if($BIOSThermalMode -eq $null) 49 | { 50 | Write-Error -Category ResourceUnavailable -CategoryTargetName "root/dcim/sysman" -CategoryTargetType "DCIM_ThermalInformation" -Message "Unable to enumerate the class 'DCIM_ThermalInformation' in the namespace 'root/dcim/sysman'" 51 | exit 1 52 | } 53 | elseif ($BIOSThermalMode -match "Quiet") 54 | { 55 | Write-host "BIOS Thermal Mode is set to 'Quiet' mode." 56 | exit 0 57 | } 58 | else 59 | { 60 | Write-Host "BIOS Thermal Mode is not set to 'Quiet' mode. Running the remediation script.." 61 | exit 1 62 | } 63 | } 64 | catch 65 | { 66 | $errMsg = $_.Exception.Message 67 | write-host $errMsg 68 | exit 1 69 | } -------------------------------------------------------------------------------- /Intune Scripts/Proactive Remediation/Intune_Detection_BIOS_AdminPW_Change.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.1 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.1 Added registry key check before updating the BIOS admin password. 23 | 24 | #> 25 | <# 26 | .Synopsis 27 | This PowerShell script checks if the BIOS AdminPW is older than 180 days and needs to be changed. 28 | IMPORTANT: Works only if you are using the "Intune_1_and_2_Remediation_BIOS_AdminPW_Setting.ps1" script to set BIOS AdminPW. 29 | IMPORTANT: This script needs a client which supports the WMI Namespace "root/dcim/sysman/wmisecurity" and the WMI class "PasswordObject". 30 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script. 31 | IMPORTANT: This script does not reboot the system to apply or query system. 32 | 33 | .DESCRIPTION 34 | PowerShell to import as Dection Script for Microsoft Endpoint Manager. This Script need to be imported in Reports/Endpoint Analytics/Proactive remediation. This File is for detection only and need a seperate script for remediation additional. 35 | NOTE: The pre-remediation detection script output is available in Intune reports in the "Pre-remediation detection output" column. 36 | NOTE: The post-remediation detection script output is available in Intune reports in the "Post-remediation detection output" column. 37 | NOTE: The remediation script log message are available on the endpoint at this path: "C:\Temp\BIOS_Profile.txt" 38 | 39 | #> 40 | try{ 41 | 42 | #Check if AdminPW is set on the machine 43 | $BIOSAdminPW = Get-CimInstance -Namespace root/dcim/sysman/wmisecurity -ClassName PasswordObject -Filter "NameId='Admin'" | Select-Object -ExpandProperty IsPasswordSet 44 | $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' 45 | Write-Output "Checking if BIOS admin password is set on the machine." 46 | 47 | if($BIOSAdminPW -eq $null) 48 | { 49 | Write-Error -Category ResourceUnavailable -CategoryTargetName "root/dcim/sysman/wmisecurity" -CategoryTargetType "PasswordObject" -Message "Unable to get the 'Admin' object in class 'PasswordObject' in the Namespace 'root/dcim/sysman/wmisecurity'" 50 | exit 1 51 | } 52 | elseif($BIOSAdminPW -match "1") 53 | { 54 | Write-Output "BIOS password is already set on the machine." 55 | if($RegKeyexist -eq "True") 56 | { 57 | # Registry key exists, password is known. 58 | # check if BIOS password older that 180 days 59 | $DateExpire = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name Update | Select-Object -ExpandProperty Update 60 | if ((Get-Date -Format yyyyMMdd) -le (Get-Date $DateExpire -Format yyyyMMdd)) 61 | { 62 | write-host "BIOS Admin password is not older than 180 days. No need to update the password." 63 | exit 0 64 | } 65 | else 66 | { 67 | Write-Host "BIOS Admin password is older than 180 days. Need to update the password." 68 | exit 1 69 | } 70 | } 71 | else 72 | { 73 | # BIOS password set but registry does not exist. 74 | # BIOS password set but unknown, need to verify if password can be changed. Run remediation. 75 | Write-Host "An unknown BIOS password is set on this machine. Need to verify if the password can be changed. Running the remediation script.." 76 | exit 1 77 | } 78 | } 79 | else 80 | { 81 | Write-Host "No BIOS Admin password is set. No need to set/update the password." 82 | exit 0 83 | } 84 | } 85 | catch 86 | { 87 | $errMsg = $_.Exception.Message 88 | write-Error $errMsg 89 | exit 1 90 | } 91 | -------------------------------------------------------------------------------- /Intune Scripts/EnterpriseAppDeployment/Readme.md: -------------------------------------------------------------------------------- 1 | # *Script Usage* 2 | The Dell_Intune_App_Publish.ps1 script has been created to help IT administrators to download and publish the Dell Supported application to there respective intune tenants. 3 | 4 | # * NOTE: Always use the latest script that is posted under Dell Git hub Repo https://github.com/dell/Endpoint-Management-Script-Library/tree/main/Intune%20Scripts/EnterpriseAppDeployment * 5 | 6 | # *Prerequisites* 7 | In order to run the script the following pre-requistes needs to be met: 8 | 1) Need to install GetMSAL powershell library using below command: 9 | Command - Install-Module -Name MSAL.PS 10 | Site Link - https://www.powershellgallery.com/packages/MSAL.PS/4.2.1.3 11 | 12 | 2) Enable power shell script execution policy 13 | 14 | # *Parameters supported:* 15 | -help : displays this help content 16 | -supportedapps : List the application names, supported versions and its AppName that needs to be passed to script 17 | -ClientId : Microsoft Intune Client identification string that needs to be passed to the script 18 | -TenantId : Microsoft Intune Tenant identification string that needs to be passed to the script 19 | -ClientSecret : Microsoft Intune Client Secret string that needs to be passed to the script 20 | -CertificateThumbprint : Microsoft Intune Certificate Thumbprint string that needs to be passed to the script 21 | -CabPath : Path of the cab file that needs to be published to Microsft Intune 22 | -AppName : Application Name that needs to be published to Microsft Intune 23 | -proxy : Proxy URL that needs to be passed to the script for downloading the files 24 | -logpath : FolderPath To store log Files. 25 | 26 | 27 | # *Script Execution:* 28 | The Script can be run in the below ways: 29 | 1) The below command display the help content of the script and different parameters that are supported: 30 | powershell.exe -file .\Dell_Intune_App_Publish.ps1 -help 31 | 2) In order to know the different Dell Apps supported and that can be published: 32 | powershell.exe -file .\Dell_Intune_App_Publish.ps1 -supportedapps -proxy "http://proxy.local:80" 33 | 4) To publish a particular dell app by downloading and deploying to Intune Tenant using client ID, Tenant ID, Client Secret: 34 | powershell.exe -file "Dell_Intune_App_Publish_V1.0.ps1" -ClientId "12345678-1234-1234-1234-123456789012" -TenantId "d66b5b8b-8b60-4b0f-8b60-123456789012" -ClientSecret "z98b5b8b8b604b0f8b60123456789012" -AppName "dcu" -proxy "http://proxy.local:80" 35 | 5) To publish a particular dell app by downloading and deploying to Intune Tenant using client ID, Tenant ID, Certificate Thumprint: 36 | powershell.exe -file "Dell_Intune_App_Publish_V1.0.ps1" -ClientId "12345678-1234-1234-1234-123456789012" -TenantId "d66b5b8b-8b60-4b0f-8b60-123456789012" -CertificateThumbprint "z98b5b8b8b604b0f8b60123456789012" -AppName "dcu" -proxy "http://proxy.local:80" 37 | 6) To publish a downloaded Dell App publish to Intune Tenant using client ID, Tenant ID, Client Secret: 38 | powershell.exe -file "Dell_Intune_App_Publish_V1.0.ps1" -ClientId "12345678-1234-1234-1234-123456789012" -TenantId "d66b5b8b-8b60-4b0f-8b60-123456789012" -ClientSecret "z98b5b8b8b604b0f8b60123456789012" -CabPath "C:\temp\dcu.cab" -proxy "http://proxy.local:80" 39 | 7) To publish a downloaded Dell App publish to Intune Tenant using client ID, Tenant ID, Certificate Thumprint: 40 | powershell.exe -file "Dell_Intune_App_Publish_V1.0.ps1" -ClientId "12345678-1234-1234-1234-123456789012" -TenantId "d66b5b8b-8b60-4b0f-8b60-123456789012" -ClientSecret "z98b5b8b8b604b0f8b60123456789012" -CabPath "C:\temp\dcu.cab" -CertificateThumbprint "z98b5b8b8b604b0f8b60123456789012" -proxy "http://proxy.local:80" 41 | 42 | Note: if the environment from which this script is being run and does not need a proxy to download files from internet then the same parameter can be removed from the command line. 43 | 44 | # *Error Code Mapping:* 45 | Below are the diffrent error codes that are returned by the script: 46 | - 0 : Success 47 | - 0 : Invalid Application Name 48 | - 2 : Invalid Parameters passed to the script 49 | - 3 : File Download Failure 50 | - 4 : Content Extraction Failure 51 | - 5 : json file parsing failure 52 | - 6 : MSAL Token Generation error 53 | - 7 : Win32 LOB App creation error 54 | - 8 : Win32 file version creation error 55 | - 9 : Win32 Lob App Place holder ID creation error 56 | - 10 : Azure Storage URI creation error 57 | - 11 : file chunk calculating uploading error 58 | - 12 : upload chunks failure 59 | - 13 : committing file upload error 60 | - 14 : Win32 App file version updation error 61 | - 15 : Sig verification failure 62 | - 16 : Prerequisite check failure 63 | - 17 : Admin Privilege Required 64 | - 18 : Directory path not Exist 65 | - 19 : dependency update failure in intune 66 | - 20 : Certificate Not Found with the given thumbprint 67 | - 21 : Section Not present in JSON 68 | - 22 : Unsupported File Extension, Supported file types are .CAB and .ZIP 69 | - 23 : Hash Verification Failure 70 | - 24 : Commit Upload status fetching failure 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## *Script Migration* 2 | The scripts are **migrated** as follows: 3 | 4 | **Endpoint-Management-Script-Library/Intune Scripts/BIOS Settings/** 5 | 1. Dell_BIOS_Baseline.ps1 6 | 2. Dell_BIOS_Boot_Order.ps1 7 | 3. Dell_BIOS_Password.ps1 8 | 4. Dell_BIOS_Persistence.ps1 9 | 5. Dell_BIOS_Setting.ps1 10 | 11 | **Endpoint-Management-Script-Library/Intune Scripts/TPM Activation and Security/** 12 | 1. Dell_BIOS_TPM_Post_Reboot.ps1 13 | 2. Dell_BIOS_TPM_Pre_Reboot.ps1 14 | 15 | **Endpoint-Management-Script-Library/Intune Scripts/UEFI Variable Settings/** 16 | 1. Dell_GetForcedNetworkFlag.ps1 17 | 2. Dell_SetForcedNetworkFlag.ps1 18 | 19 | # *Intune client script library* 20 | PowerShell scripting for Dell Client BIOS Direct WMI API with DMTF CIM or WMI. 21 | Sample scripts are written in PowerShell that illustrates the usage of Dell Client BIOS Direct WMI API with WMI to manage Dell clients. These scripts can be deployed from Intune management console to manage the Dell commercial client systems. 22 | 23 | ## *Agentless BIOS manageablity* 24 | You cannot configure the Dell client systems without installing a system management agent such as Dell Command Suite. These agents equip the system with the Dell interfaces, services, console UI, and CLI-based tools. When you introduce agent software into the system, updates and redeployment plans must be maintained. 25 | 26 | There is another option to manage the Dell client devices without adding any agents in the system. Dell offers a PowerShell script library. This script library contains PowerShell samples on how to use the WMI interface to leverage the default namespaces that are available to manage the Dell client devices without any additional agents or tools. 27 | 28 | Customers can experience zero-touch or agentless management aspects of the Dell commercial client platforms. The Direct WMI interface is available on the Dell commercial client systems (released to market after the calendar year 2018). You can manage the BIOS configurations on the Dell commercial client systems directly from WMI, without using additional agents or applications. 29 | 30 | For more information about Agentless BIOS manageability, see [https://downloads.dell.com/manuals/common/dell-agentless-client-manageability.pdf] 31 | 32 | ## *Windows Management Instrumentation and PowerShell* 33 | Windows Management Instrumentation (WMI) is the infrastructure to manage the data and operations on Windows based operating systems. 34 | 35 | PowerShell offers cross-platform task automation and configuration management framework through command-line instructions and scripting language. 36 | 37 | Most of the Dell commercial client systems are Windows-based, WMI and PowerShell are available in the IT infrastructure. This allows the IT professionals to integrate the scripts with their existing infrastructure or develop custom scripts based on their requirements. Microsoft has done a great job enhancing the PowerShell capabilities to integrate and manage WMI infrastructure. 38 | 39 | The Dell commercial client BIOS offers configurable entities through WMI, and the script library provides sample scripts to accomplish the tasks. This method configures the Dell business client systems that contain the common interface across multiple brands, including Latitude, OptiPlex, Precision, and XPS laptops. It enhances the hardware management features and does not change across the various versions of the Windows operating systems. 40 | 41 | ## *Learning more about WMI and PowerShell* 42 | For more details on WMI, see [https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-start-page] 43 | For more details on PowerShell, see [https://docs.microsoft.com/en-us/powershell/scripting/overview?view=powershell-7] 44 | For more details on Agentless BIOS manageability, see [https://downloads.dell.com/manuals/common/dell-agentless-client-manageability.pdf] 45 | 46 | ## *Microsoft Intune* 47 | Microsoft Intune is a cloud-based service that focuses on Mobile Device Management (MDM). 48 | For more details on Microsoft Intune, see 49 | [https://docs.microsoft.com/en-us/mem/intune/fundamentals/what-is-intune] 50 | 51 | ## *Deploying a PowerShell script from Intune* 52 | The Microsoft Intune management extension allows you to upload the PowerShell scripts in Intune. You can run these scripts on the systems which are running on Windows 10 operating systems. The management extension enhances the Mobile Device Management (MDM) capabilities. 53 | For more information about Deploying a PowerShell script from Intune, see 54 | [https://docs.microsoft.com/en-us/mem/intune/apps/intune-management-extension] 55 | 56 | ## *Intune client script library* 57 | 58 | This GitHub library offers the PowerShell scripts that illustrate the usage of the agentless BIOS manageability to perform the following BIOS operations: 59 | * Configure BIOS passwords 60 | * Configure BIOS attribute(s) 61 | * Configure BIOS baseline (example, Reset BIOS to default factory settings) 62 | * Configure Trusted Platform Module (TPM) 63 | * Configure Persistence (Absolute) 64 | * Configure Boot Order 65 | 66 | ### *Prerequisites* 67 | * Dell commercial client systems that are released to market after calendar year 2018 68 | * Windows operating system 69 | * PowerShell 5.0 or later 70 | 71 | ## *Support* 72 | This code is provided to help the open-source community and currently not supported by Dell. 73 | 74 | ## *Provide feedback or report an issue* 75 | You can provide further feedback or report an issue by using the following link 76 | [https://github.com/dell/IntuneScriptLibrary] 77 | 78 | 79 | -------------------------------------------------------------------------------- /Intune Scripts/Proactive Remediation/Intune_Remediation_BIOS_Thermalmode_Setting.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.1 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.0 Initial version 23 | 1.0.1 Replacing WMI commands with Dell | Command Monitor commands to get/set the BIOS Thermal Management setting. 24 | Additionally, registry check is performed to get the right BIOS admin password. 25 | 26 | #> 27 | 28 | <# 29 | .Synopsis 30 | This PowerShell script is for remediation by MS Endpoint Manager. This script checks if the client BIOS Thermal Management and sets it to "Quiet" using Dell | Command Monitor. 31 | IMPORTANT: This script needs a client installation of Dell | Command Monitor https://www.dell.com/support/kbdoc/en-us/000177080/dell-command-monitor 32 | IMPORTANT: This script does not reboot the system to apply or query any settings. 33 | IMPORTANT: Thi script checks if any BIOS admin password exists using a WMI query and uses the same as an authorization token while setting the BIOS Thermal management using DCM. 34 | IMPORTANT: WMI BIOS is supported only on devices which developt after 2018, older devices does not supported by this powershell 35 | .DESCRIPTION 36 | This Powershell script using Dell | Command Monitor for setting Thermal Management to 'Quiet' on the machine. 37 | This script needs to be imported in Reports/Endpoint Analytics/Proactive remediation. This File is for remediation only. 38 | NOTE: The remediation script errors if any will be available in Intune reports in the "Remediation Errors" column. 39 | 40 | #> 41 | 42 | $AdminPw = "" 43 | 44 | try 45 | { 46 | # Check BIOS AttributName ThermalSetting is Value Quiet 47 | $BIOSThermalMode= Switch ( Get-CimInstance -Namespace root/dcim/sysman -ClassName DCIM_ThermalInformation -Filter "AttributeName='Thermal Mode'"| Select-Object -ExpandProperty CurrentValue) 48 | { 49 | 0 {"Optimized"} 50 | 1 {"Cool"} 51 | 2 {"Quiet"} 52 | 3 {"Performance"} 53 | } 54 | if($BIOSThermalMode -eq $null) 55 | { 56 | Write-Error -Category ResourceUnavailable -CategoryTargetName "root/dcim/sysman" -CategoryTargetType "DCIM_ThermalInformation" -Message "Unable to enumerate the class 'DCIM_ThermalInformation' in the namespace 'root/dcim/sysman'" 57 | exit 1 58 | } 59 | else 60 | { 61 | $CheckAdminPW = Get-CimInstance -Namespace root/dcim/sysman/wmisecurity -ClassName PasswordObject -Filter "NameId='Admin'" | Select-Object -ExpandProperty IsPasswordSet 62 | if($CheckAdminPW -eq $null) 63 | { 64 | Write-Error -Category ResourceUnavailable -CategoryTargetName "root/dcim/sysman/wmisecurity" -CategoryTargetType "PasswordObject" -Message "Unable to get the 'Admin' object in class 'PasswordObject' in the Namespace 'root/dcim/sysman/wmisecurity'" 65 | exit 1 66 | } 67 | elseif($CheckAdminPW -match "1") 68 | { 69 | #BIOS admin password is set. Verifying if the registry path exists. 70 | $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' 71 | if($RegKeyexist -eq "True") 72 | { 73 | # Get BIOS AdminPW for this device 74 | $PWKey = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name BIOS | Select-Object -ExpandProperty BIOS 75 | $serviceTag = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name ServiceTag | Select-Object -ExpandProperty ServiceTag 76 | $AdminPw = "$serviceTag$PWKey" 77 | } 78 | else 79 | { 80 | Write-Error "Unknown BIOS admin password on the system. This password needs to be cleared by the user." 81 | exit 1 82 | } 83 | } 84 | 85 | $ThermalModeSetStatus = Get-CimInstance -Namespace root\dcim\sysman -ClassName DCIM_ThermalInformation | Invoke-CimMethod -MethodName ChangeThermalMode -Arguments @{AttributeName=@("Thermal Mode");AttributeValue=@("2");AuthorizationToken=$AdminPw} 86 | 87 | if($ThermalModeSetStatus[0].SetResult[0] -eq 0) 88 | { 89 | Write-Host "BIOS Thermal Mode is set to 'Quiet' mode." 90 | exit 0 91 | } 92 | elseif($ThermalModeSetStatus[0].SetResult[0] -eq 2) 93 | { 94 | # incorrect BIOS admin pw 95 | Write-Error "Authentication Failure : The BIOS password used is incorrect." 96 | exit 1 97 | } 98 | else 99 | { 100 | # failure - possible value out is out of range or invalid or readonly. 101 | Write-Error "Set Failure : The possible value is out of range or invalid or read-only." 102 | exit 1 103 | } 104 | } 105 | } 106 | catch 107 | { 108 | $errMsg = $_.Exception.Message 109 | write-host $errMsg 110 | exit 1 111 | } -------------------------------------------------------------------------------- /Intune Scripts/UEFI Variable Settings/Dell_SetForcedNetworkFlag.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Mazahir Ahmad Khan 3 | _version_ = 1.0 4 | 5 | Copyright © 2022 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | #> 17 | 18 | <# 19 | .Synopsis 20 | Set-UEFIforcedNetworkFlag is used to set FORCED_NETWORK_FLAG value. 21 | UnComment Last three lines or add EXAMPLE lines at bottom to run the script. 22 | .DESCRIPTION 23 | FORCED_NETWORK_FLAG is set to 1 using this script. 24 | 25 | .EXAMPLE 26 | $bytes = New-Object Byte[](4) 27 | $bytes[0]=1 28 | Set-UEFIforcedNetworkFlag -VariableName FORCED_NETWORK_FLAG -Namespace "{616e2ea6-af89-7eb3-f2ef-4e47368a657b}" -ByteArray $bytes 29 | #> 30 | 31 | $definition = @' 32 | using System; 33 | using System.Runtime.InteropServices; 34 | using System.Text; 35 | 36 | public class UEFINative 37 | { 38 | [DllImport("kernel32.dll", SetLastError = true)] 39 | public static extern UInt32 GetFirmwareEnvironmentVariableA(string lpName, string lpGuid, [Out] Byte[] lpBuffer, UInt32 nSize); 40 | 41 | [DllImport("kernel32.dll", SetLastError = true)] 42 | public static extern UInt32 SetFirmwareEnvironmentVariableA(string lpName, string lpGuid, Byte[] lpBuffer, UInt32 nSize); 43 | } 44 | '@ 45 | 46 | $uefiNative = Add-Type $definition -PassThru 47 | 48 | 49 | function Set-UEFIforcedNetworkFlag 50 | { 51 | [cmdletbinding()] 52 | Param( 53 | [Parameter(Mandatory=$true, HelpMessage="Enter {616e2ea6-af89-7eb3-f2ef-4e47368a657b} GUIID for FORCED_NETWORK_FLAG")] 54 | [ValidateNotNullOrEmpty()] 55 | [ValidateSet("{616e2ea6-af89-7eb3-f2ef-4e47368a657b}")] 56 | [String]$Namespace, 57 | 58 | [Parameter(Mandatory=$true, HelpMessage="Enter FORCED_NETWORK_FLAG")] 59 | [ValidateNotNullOrEmpty()] 60 | [ValidateSet("FORCED_NETWORK_FLAG")] 61 | [String]$VariableName, 62 | 63 | [Parameter()] 64 | [String]$Value = "", 65 | 66 | [Parameter()] 67 | [Byte[]]$ByteArray = $null 68 | ) 69 | 70 | BEGIN { 71 | $rc = Set-Privilege -Privilege SeSystemEnvironmentPrivilege 72 | if ($rc -eq 0) 73 | { 74 | Write-Error "Unable to change privilege" 75 | return "" 76 | } 77 | } 78 | PROCESS { 79 | if ($Value -ne "") 80 | { 81 | $enc = [System.Text.Encoding]::ASCII 82 | $bytes = $enc.GetBytes($Value) 83 | Write-Verbose "Setting variable $VariableName to a string value with $($bytes.Length) characters" 84 | $rc = $uefiNative[0]::SetFirmwareEnvironmentVariableA($VariableName, $Namespace, $bytes, $bytes.Length) 85 | } 86 | else 87 | { 88 | Write-Verbose "Setting variable $VariableName to a byte array with $($ByteArray.Length) bytes" 89 | $rc = $uefiNative[0]::SetFirmwareEnvironmentVariableA($VariableName, $Namespace, $ByteArray, $ByteArray.Length) 90 | } 91 | if ($rc -eq 0) 92 | { 93 | Write-Error "Unable to set variable $VariableName from namespace $Namespace" 94 | } 95 | } 96 | END { 97 | $rc = Set-Privilege -Privilege SeSystemEnvironmentPrivilege -Disable 98 | if ($rc -eq 0) 99 | { 100 | Write-Error "Unable to change privilege" 101 | return "" 102 | } 103 | } 104 | 105 | } 106 | 107 | 108 | function Set-Privilege 109 | { 110 | [cmdletbinding( 111 | ConfirmImpact = 'low', 112 | SupportsShouldProcess = $false 113 | )] 114 | 115 | [OutputType('System.Boolean')] 116 | 117 | Param( 118 | 119 | [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$False,HelpMessage='pass SeSystemEnvironmentPrivilege')] 120 | [ValidateNotNullOrEmpty()] 121 | [ValidateSet("SeSystemEnvironmentPrivilege")] 122 | [String]$Privilege, 123 | 124 | [Parameter(Position=1)] 125 | [ValidateNotNullOrEmpty()] 126 | $ProcessId = $pid, 127 | 128 | [Switch]$Disable 129 | ) 130 | 131 | BEGIN { 132 | 133 | ${CmdletName} = $Pscmdlet.MyInvocation.MyCommand.Name 134 | 135 | $definition = @' 136 | using System; 137 | using System.Runtime.InteropServices; 138 | 139 | public class AdjPriv 140 | { 141 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 142 | internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); 143 | 144 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 145 | internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); 146 | 147 | [DllImport("advapi32.dll", SetLastError = true)] 148 | internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); 149 | 150 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 151 | internal struct TokPriv1Luid 152 | { 153 | public int Count; 154 | public long Luid; 155 | public int Attr; 156 | } 157 | 158 | internal const int SE_PRIVILEGE_ENABLED = 0x00000002; 159 | internal const int SE_PRIVILEGE_DISABLED = 0x00000000; 160 | internal const int TOKEN_QUERY = 0x00000008; 161 | internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; 162 | 163 | public static bool EnablePrivilege(long processHandle, string privilege, bool disable) 164 | { 165 | bool retVal; 166 | TokPriv1Luid tp; 167 | IntPtr hproc = new IntPtr(processHandle); 168 | IntPtr htok = IntPtr.Zero; 169 | retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); 170 | tp.Count = 1; 171 | tp.Luid = 0; 172 | if(disable) 173 | { 174 | tp.Attr = SE_PRIVILEGE_DISABLED; 175 | } 176 | else 177 | { 178 | tp.Attr = SE_PRIVILEGE_ENABLED; 179 | } 180 | retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); 181 | retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); 182 | return retVal; 183 | } 184 | } 185 | '@ 186 | 187 | 188 | 189 | } # end BEGIN 190 | 191 | PROCESS { 192 | 193 | $processHandle = (Get-Process -id $ProcessId).Handle 194 | if ($processHandle -eq 0) 195 | { 196 | Write-Error "Unable to get process" 197 | return "" 198 | } 199 | 200 | $adjprivobj = Add-Type $definition -PassThru 201 | $adjprivobj[0]::EnablePrivilege($processHandle, $Privilege, $Disable) 202 | 203 | } # end PROCESS 204 | 205 | END { Write-Verbose "Function ${CmdletName} finished." } 206 | 207 | } # end Function Set-Privilege 208 | 209 | #$bytes = New-Object Byte[](4) 210 | #$bytes[0]=1 211 | #Set-UEFIforcedNetworkFlag -VariableName FORCED_NETWORK_FLAG -Namespace "{616e2ea6-af89-7eb3-f2ef-4e47368a657b}" -ByteArray $bytes 212 | -------------------------------------------------------------------------------- /Intune Scripts/UEFI Variable Settings/Dell_GetForcedNetworkFlag.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Mazahir Ahmad Khan 3 | _version_ = 1.0 4 | 5 | Copyright © 2022 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | #> 17 | 18 | <# 19 | .Synopsis 20 | Get-UEFIforcedNetworkFlag is used to get FORCED_NETWORK_FLAG value. 21 | .DESCRIPTION 22 | 1- Add this script in https://endpoint.microsoft.com/->Home->->Reports->Endpoint Analytics->Proactive Remediation->Create Script Package 23 | 2- output is available in https://endpoint.microsoft.com/->Home->Reports->Endpoint Analytics->script name->Device Status->Pre-remediation detection output(Add Column if not visible) 24 | 25 | .EXAMPLE 26 | Get-UEFIforcedNetworkFlag -VariableName FORCED_NETWORK_FLAG -Namespace "{616e2ea6-af89-7eb3-f2ef-4e47368a657b}" -AsByteArray 27 | #> 28 | $definition = @' 29 | using System; 30 | using System.Runtime.InteropServices; 31 | using System.Text; 32 | 33 | public class UEFINative 34 | { 35 | [DllImport("kernel32.dll", SetLastError = true)] 36 | public static extern UInt32 GetFirmwareEnvironmentVariableA(string lpName, string lpGuid, [Out] Byte[] lpBuffer, UInt32 nSize); 37 | 38 | [DllImport("kernel32.dll", SetLastError = true)] 39 | public static extern UInt32 SetFirmwareEnvironmentVariableA(string lpName, string lpGuid, Byte[] lpBuffer, UInt32 nSize); 40 | } 41 | '@ 42 | 43 | $uefiNative = Add-Type $definition -PassThru 44 | 45 | function Get-UEFIforcedNetworkFlag 46 | { 47 | 48 | [cmdletbinding()] 49 | Param( 50 | [Parameter(Mandatory=$true,HelpMessage="Enter {616e2ea6-af89-7eb3-f2ef-4e47368a657b} GUIID for FORCED_NETWORK_FLAG")] 51 | [ValidateNotNullOrEmpty()] 52 | [ValidateSet("{616e2ea6-af89-7eb3-f2ef-4e47368a657b}")] 53 | [String]$Namespace, 54 | 55 | [Parameter(Mandatory=$true, HelpMessage="Enter FORCED_NETWORK_FLAG")] 56 | [ValidateNotNullOrEmpty()] 57 | [ValidateSet("FORCED_NETWORK_FLAG")] 58 | [String]$VariableName, 59 | 60 | [Parameter(HelpMessage="enter this switch to consider output as byte array.")] 61 | [Switch]$AsByteArray = $false 62 | ) 63 | 64 | BEGIN { 65 | $rc = Set-Privilege -Privilege SeSystemEnvironmentPrivilege 66 | if ($rc -eq 0) 67 | { 68 | Write-Error "Unable to change privilege" 69 | return "" 70 | } 71 | } 72 | PROCESS { 73 | $size = 1024 74 | $result = New-Object Byte[](1024) 75 | $rc = $uefiNative[0]::GetFirmwareEnvironmentVariableA($VariableName, $Namespace, $result, $size) 76 | if ($rc -eq 0) 77 | { 78 | Write-Error "Unable to retrieve variable $VariableName from namespace $Namespace" 79 | return "" 80 | } 81 | else 82 | { 83 | Write-Verbose "Variable $VariableName retrieved with $rc bytes" 84 | if ($AsByteArray) 85 | { 86 | try 87 | { 88 | [System.Array]::Resize([ref] $result, $rc) 89 | return $result 90 | } 91 | catch 92 | { 93 | Write-error "failed to resize uefi variable as byte array" 94 | return "" 95 | } 96 | } 97 | else 98 | { 99 | try 100 | { 101 | $enc = [System.Text.Encoding]::ASCII 102 | return $enc.GetString($result) 103 | } 104 | catch 105 | { 106 | Write-error "failed to encode uefi variable into ascii string" 107 | return "" 108 | } 109 | } 110 | } 111 | } 112 | END { 113 | $rc = Set-Privilege -Privilege SeSystemEnvironmentPrivilege -Disable 114 | if ($rc -eq 0) 115 | { 116 | Write-Error "Unable to change privilege" 117 | return "" 118 | } 119 | } 120 | } 121 | 122 | function Set-Privilege 123 | { 124 | [cmdletbinding( 125 | ConfirmImpact = 'low', 126 | SupportsShouldProcess = $false 127 | )] 128 | 129 | [OutputType('System.Boolean')] 130 | 131 | Param( 132 | 133 | [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$False,HelpMessage='pass SeSystemEnvironmentPrivilege')] 134 | [ValidateNotNullOrEmpty()] 135 | [ValidateSet("SeSystemEnvironmentPrivilege")] 136 | [String]$Privilege, 137 | 138 | [Parameter(Position=1)] 139 | [ValidateNotNullOrEmpty()] 140 | $ProcessId = $pid, 141 | 142 | [Switch]$Disable 143 | ) 144 | 145 | BEGIN { 146 | 147 | ${CmdletName} = $Pscmdlet.MyInvocation.MyCommand.Name 148 | 149 | $definition = @' 150 | using System; 151 | using System.Runtime.InteropServices; 152 | 153 | public class AdjPriv 154 | { 155 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 156 | internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); 157 | 158 | [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] 159 | internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); 160 | 161 | [DllImport("advapi32.dll", SetLastError = true)] 162 | internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); 163 | 164 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 165 | internal struct TokPriv1Luid 166 | { 167 | public int Count; 168 | public long Luid; 169 | public int Attr; 170 | } 171 | 172 | internal const int SE_PRIVILEGE_ENABLED = 0x00000002; 173 | internal const int SE_PRIVILEGE_DISABLED = 0x00000000; 174 | internal const int TOKEN_QUERY = 0x00000008; 175 | internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; 176 | 177 | public static bool EnablePrivilege(long processHandle, string privilege, bool disable) 178 | { 179 | bool retVal; 180 | TokPriv1Luid tp; 181 | IntPtr hproc = new IntPtr(processHandle); 182 | IntPtr htok = IntPtr.Zero; 183 | retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); 184 | tp.Count = 1; 185 | tp.Luid = 0; 186 | if(disable) 187 | { 188 | tp.Attr = SE_PRIVILEGE_DISABLED; 189 | } 190 | else 191 | { 192 | tp.Attr = SE_PRIVILEGE_ENABLED; 193 | } 194 | retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); 195 | retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); 196 | return retVal; 197 | } 198 | } 199 | '@ 200 | 201 | 202 | 203 | } # end BEGIN 204 | 205 | PROCESS { 206 | 207 | $processHandle = (Get-Process -id $ProcessId).Handle 208 | if ($processHandle -eq 0) 209 | { 210 | Write-Error "Unable to get process" 211 | return "" 212 | } 213 | 214 | $adjprivobj = Add-Type $definition -PassThru 215 | $adjprivobj[0]::EnablePrivilege($processHandle, $Privilege, $Disable) 216 | 217 | } # end PROCESS 218 | 219 | END { Write-Verbose "Function ${CmdletName} finished." } 220 | 221 | } # end Function Set-Privilege 222 | 223 | Write-Host(Get-UEFIforcedNetworkFlag -VariableName FORCED_NETWORK_FLAG -Namespace "{616e2ea6-af89-7eb3-f2ef-4e47368a657b}" -AsByteArray) 224 | -------------------------------------------------------------------------------- /Intune Scripts/Proactive Remediation/Intune_Remediation_BIOS_AdminPW_Setting.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Sven Riebe 3 | _version_ = 1.0.2 4 | _Dev_Status_ = Test 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | No implied support and test in test environment/device before using in any production environment. 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | #> 19 | 20 | <#Version Changes 21 | 22 | 1.0.1 Switch of BIOS Setting by Dell Command | Monitor to WMI agentless 23 | 1.0.2 Add new RegKey for date of update will be written to registry 24 | 25 | #> 26 | 27 | <# 28 | .Synopsis 29 | This PowerShell script is for remediation by MS Endpoint Manager. This script will set/update the BIOS AdminPW on a Dell machine by using WMI. 30 | IMPORTANT: This script will SET/UPDATE BIOS ADMIN password if the password is not set or expired after 180 days. 31 | IMPORTANT: This script needs a client which supports the WMI Namespace "root/dcim/sysman/wmisecurity" and the WMI class "PasswordObject". 32 | IMPORTANT: WMI BIOS is supported only on devices which developed after 2018, older devices do not supported by this powershell script. 33 | IMPORTANT: This script does not reboot the system to apply or query system. 34 | IMPORTANT: The parameters $PWKey and $PWTime can be changed as per the requirements. 35 | 36 | .DESCRIPTION 37 | Powershell using WMI for setting AdminPW on the machine. The script checks if any PW is exist and can setup new and change PW. 38 | This Script need to be imported in Reports/Endpoint Analytics/Proactive remediation. This File is for remediation only and need a seperate script for detection additional. 39 | NOTE: The remediation script log message are available on the endpoint at this path: "C:\Temp\BIOS_Profile.txt" 40 | 41 | .EXAMPLE 42 | This example provides the BIOS admin password that will be set if its not previously set or expired. The admin password is set using the service tag of the system. 43 | Ex: $Servicetag= "FW2DLQ2" 44 | $PWkey = "Dell2023" 45 | The admin password set is "FW2DLQ2Dell2023" 46 | 47 | #> 48 | 49 | 50 | #Variable for change 51 | $PWKey = "Dell2023" #Sure-Key of AdminPW 52 | $PWTime = "180" # Days a password need exist before it will be change 53 | 54 | 55 | 56 | #Variable not for change 57 | $PWset = Get-CimInstance -Namespace root/dcim/sysman/wmisecurity -ClassName PasswordObject -Filter "NameId='Admin'" | Select-Object -ExpandProperty IsPasswordSet 58 | $DateTransfer = (Get-Date).AddDays($PWTime) 59 | $PWstatus = "" 60 | #$DeviceName = Get-CimInstance -ClassName win32_computersystem | select -ExpandProperty Name 61 | $serviceTag = Get-CimInstance -ClassName win32_bios | Select-Object -ExpandProperty SerialNumber 62 | $AdminPw = "$serviceTag$PWKey" 63 | $Date = Get-Date 64 | $PWKeyOld = "" 65 | $serviceTagOld = "" 66 | $AdminPwOld = "" 67 | $PATH = "C:\Temp\" 68 | 69 | 70 | #check if c:\temp exist / check if RegKey exisit 71 | if (!(Test-Path $PATH)) {New-Item -Path $PATH -ItemType Directory} 72 | $RegKeyexist = Test-Path 'HKLM:\SOFTWARE\Dell\BIOS' 73 | 74 | #Logging device data 75 | Write-Output $env:COMPUTERNAME | out-file "$PATH\BIOS_Profile.txt" -Append 76 | Write-Output "ServiceTag: $serviceTag" | out-file "$PATH\BIOS_Profile.txt" -Append 77 | Write-Output "Profile install at: $Date" | out-file "$PATH\BIOS_Profile.txt" -Append 78 | 79 | #Connect to the SecurityInterface WMI class 80 | $SecurityInterface = Get-WmiObject -Namespace root\dcim\sysman\wmisecurity -Class SecurityInterface 81 | 82 | #Checking RegistryKey availbility 83 | Write-Output "Starting the remediation script.." 84 | 85 | if ($RegKeyexist -eq "True") 86 | { 87 | $PWKeyOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name BIOS | Select-Object -ExpandProperty BIOS 88 | $serviceTagOld = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Dell\BIOS\' -Name ServiceTag | Select-Object -ExpandProperty ServiceTag 89 | $AdminPwOld = "$serviceTagOld$PWKeyOld" 90 | 91 | Write-Output "Registry Key exist" | out-file "$PATH\BIOS_Profile.txt" -Append 92 | # Encoding BIOS Password 93 | $Encoder = New-Object System.Text.UTF8Encoding 94 | $Bytes = $Encoder.GetBytes($AdminPwOld) 95 | } 96 | else 97 | { 98 | New-Item -path "hklm:\software\Dell\BIOS" -Force 99 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value "" -type string -Force 100 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value "" -type string -Force 101 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value "" -type string -Force 102 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "" -type string -Force 103 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value (Get-Date -Format yyyy-MM-dd) -type string -Force 104 | 105 | Write-Output "Registry Key is set" | out-file "$PATH\BIOS_Profile.txt" -Append 106 | } 107 | 108 | #Checking AdminPW is not set on the machine 109 | Write-Output "Checking if the BIOS Password is set on the system" 110 | 111 | if($PWset -eq $null) 112 | { 113 | Write-Error -Category ResourceUnavailable -CategoryTargetName "root/dcim/sysman/wmisecurity" -CategoryTargetType "PasswordObject" -Message "Unable to get the 'Admin' object in class 'PasswordObject' in the Namespace 'root/dcim/sysman/wmisecurity'" 114 | Exit 1 115 | } 116 | elseif ($PWset -eq $false) 117 | { 118 | Write-Output "BIOS password is not set on the system." 119 | 120 | $PWstatus = $SecurityInterface.SetNewPassword(0,0,0,"Admin","",$AdminPw) | Select-Object -ExpandProperty Status 121 | 122 | #Setting of AdminPW was successful 123 | 124 | If ($PWstatus -eq 0) 125 | { 126 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $PWKey -type string -Force 127 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "ServiceTag" -value $serviceTag -type string -Force 128 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Date" -value $Date -type string -Force 129 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Ready" -type string -Force 130 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value (Get-Date $DateTransfer -Format yyyy-MM-dd) -type string -Force 131 | 132 | Write-Output "BIOS admin password is set successfully for first time." | out-file "$PATH\BIOS_Profile.txt" -Append 133 | Write-Host "BIOS admin password is set successfully for first time." 134 | Exit 0 135 | } 136 | else 137 | { 138 | #Setting of AdminPW was unsuccessful 139 | 140 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Error" -type string -Force 141 | Write-Output "ERROR: BIOS admin password could not set." | out-file "$PATH\BIOS_Profile.txt" -Append 142 | Write-Error "ERROR: BIOS admin password could not set." 143 | Exit 1 144 | } 145 | } 146 | else 147 | { 148 | Write-Output "BIOS password is already set on the system." 149 | #Check if AdminPW is the same if not it will change AdminPW to new AdminPW 150 | #Compare old and new AdminPW are equal 151 | If ($AdminPw -eq $AdminPwOld) 152 | { 153 | # Change the pwkey to generate a new password. 154 | Write-Output "The parameters PWKey and PWTime in the remediation script need to be updated for the BIOS Admin password update." | out-file "$PATH\BIOS_Profile.txt" -Append 155 | Write-Error "The parameters PWKey and PWTime in the remediation script need to be updated for the BIOS Admin password update." 156 | Exit 1 157 | } 158 | else 159 | { 160 | #Old and new AdminPW are different make AdminPW change 161 | $PWstatus = $SecurityInterface.SetNewPassword(1,$Bytes.Length,$Bytes,"Admin",$AdminPwOld,$AdminPw) | Select-Object -ExpandProperty Status 162 | 163 | #Checking if change was successful 164 | If($PWstatus -eq 0) 165 | { 166 | Write-Output "BIOS admin password is updated successfully." | out-file "$PATH\BIOS_Profile.txt" -Append 167 | Write-Host "BIOS admin password is updated successfully." 168 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Ready" -type string -Force 169 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "BIOS" -value $PWKey -type string -Force 170 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Update" -value (Get-Date $DateTransfer -Format yyyy-MM-dd) -type string -Force 171 | Exit 0 172 | } 173 | else 174 | { 175 | #Checking if change was unsuccessful. Most reason is there is a AdminPW is set by user or admin before the profile is enrolled or RegistryKey does not exist 176 | New-Itemproperty -path "hklm:\software\Dell\BIOS" -name "Status" -value "Unknown" -type string -Force 177 | Write-Output "Unknown BIOS admin password on this machine. This password needs to be cleared by the user." | out-file "$PATH\BIOS_Profile.txt" -Append 178 | Write-Error "Unknown BIOS admin password on this machine. This password needs to be cleared by the user." 179 | Exit 1 180 | } 181 | } 182 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /Intune Scripts/System Information/Dell_Warranty_Bulk.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Prateek Vishwakarma 3 | _version_ = 1.0 4 | 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | #> 17 | 18 | <# 19 | .Synopsis 20 | IT Administrators need a way to retrieve the warranty entitlement information of 21 | list of client systems. 22 | For example - A list of client systems for which warranty expires in next 30 days. 23 | This helps with proactive plans of warranty renewal and inventory/audits. 24 | 25 | .DESCRIPTION 26 | Get-DellWarrantyInBulk cmdlet can be used to fetch warranty entitlement information 27 | of list of client systems. 28 | This cmdlet can be executed on a single windows endpoint, and need not deployed to 29 | all the client systems. 30 | 31 | Scenario A : Using Get-DellWarrantyInBulk cmdlet, An Intune based IT Administrative 32 | user can just use their Intune UPN and Password to fetch a list of service tags 33 | of their Dell IntuneManagedDevices and then bulk query the warranty entitlement 34 | status using Dell Command | Warranty. 35 | 36 | Scenario B : Using Get-DellWarrantyInBulk cmdlet, A Microsoft Endpoint Manager / 37 | Configuration Manager (MEMCM) based IT Administrative user can fetch the list 38 | of service tags from the MEMCM Database in a CSV format and then pass the same 39 | as input to Get-DellWarrantyInBulk cmdlet. 40 | 41 | IMPORTANT: 42 | 1. Make sure you are using latest Powershell version 5 or newer to execute 43 | this cmdlet. Execute "Get-Host" to check the version. 44 | 2. Make sure Dell Command | Warranty application is installed on the endpoint. 45 | https://www.dell.com/support/kbdoc/en-us/000146749/dell-command-warranty 46 | 3. Make sure you have working internet connection to query warranty information. 47 | 4. This script installs "Microsoft.Graph.Intune" powershell module from 48 | PSGallery, if user wishes to fetch Dell service tags from Intune environment. 49 | 50 | Following is description of Get-DellWarrantyInBulk cmdlet parameters - 51 | 52 | - AdminUPN, [string], REQUIRED (Scenario A), 53 | User Principal Name of Intune Administrative user. 54 | 55 | - AdminPwd, [SecureString], REQUIRED (Scenario A), 56 | Password of adminUPN user (in a SecureString format). 57 | 58 | - InputCSV, [string], REQUIRED (Scenario B), 59 | Full path to CSV file (containing list of Dell service tags). 60 | 61 | - OutputDir, [string], OPTIONAL, 62 | Path of Output directory (where warranty details will be exported). 63 | The cmdlet generates output in $PSScriptRoot path, in case user does not sets 64 | OutputDir. 65 | 66 | - Filter, [string], OPTIONAL, 67 | Optional filters that can be used while querying warranty information. 68 | e.g. 69 | - ActiveWarranty - Exports active warranty entitlement information. 70 | - WarrantyExpiringIn30Days - Exports warranty entitlement information where 71 | entitlement expires in 30 days. 72 | - ExpiredWarranty - Exports expired warranty entitlement information. 73 | Default: AnyWarranty - Exports all warranty entitlement information. 74 | 75 | - ProxyServer, [string], OPTIONAL, 76 | Proxy server URL without port e.g., https://. 77 | 78 | - ProxyPort, [string], OPTIONAL, 79 | Proxy server port e.g., 80. 80 | 81 | - ProxyUser, [string], OPTIONAL, 82 | Proxy user name. 83 | 84 | - ProxyPassword,[SecureString], OPTIONAL, 85 | Proxy user password (in a SecureString format). 86 | 87 | 88 | NOTE: 89 | Following commands can be used to convert plaintext password to SecureString: 90 | 91 | $password = "" 92 | [Security.SecureString]$securePassword = ConvertTo-SecureString $password ` 93 | -AsPlainText -Force 94 | 95 | .EXAMPLE 96 | This example shows how to fetch bulk warranty in an intune environment (Scenario A). 97 | Get-DellWarrantyInBulk -AdminUPN "user@company.com" -AdminPwd $securePassword 98 | 99 | .EXAMPLE 100 | This example shows how to fetch bulk warranty (Scenario A) WarrantyExpiringIn30Days 101 | entitlements. 102 | Get-DellWarrantyInBulk -AdminUPN "user@company.com" -AdminPwd $securePassword ` 103 | -Filter WarrantyExpiringIn30Days 104 | 105 | .EXAMPLE 106 | This example shows how to fetch bulk warranty (Scenario A) behind Proxy. 107 | Get-DellWarrantyInBulk -AdminUPN "user@company.com" -AdminPwd $securePassword ` 108 | -ProxyServer https:// -ProxyPort 80 -ProxyUser "proxy_user_name" ` 109 | -ProxyPassword $secureProxyUserPassword 110 | 111 | .EXAMPLE 112 | This example shows how to fetch bulk warranty in a MEMCM envronment (Scenario B). 113 | Get-DellWarrantyInBulk -InputCSV 115 | 116 | .EXAMPLE 117 | This example shows how to fetch bulk warranty (Scenario B) ExpiredWarranty. 118 | entitlements 119 | Get-DellWarrantyInBulk -InputCSV -Filter ExpiredWarranty 121 | 122 | .EXAMPLE 123 | This example shows how to fetch bulk warranty (Scenario B) behind proxy. 124 | Get-DellWarrantyInBulk -InputCSV ` 126 | -ProxyServer https:// -ProxyPort 80 -ProxyUser "proxy_user_name" ` 127 | -ProxyPassword $secureProxyUserPassword 128 | 129 | #> 130 | 131 | Function Get-DellWarrantyInBulk 132 | { 133 | [CmdletBinding(DefaultParameterSetName = 'UsingGraph')] 134 | param( 135 | [parameter(Mandatory=$true, 136 | ParameterSetName = 'UsingGraph', 137 | HelpMessage="Enter User Principal Name of Intune Administrative user ")] 138 | [ValidateNotNullOrEmpty()] 139 | [string]$AdminUPN, 140 | 141 | [parameter(Mandatory=$true, 142 | ParameterSetName = 'UsingGraph', 143 | HelpMessage="Enter password for adminUPN in a SecureString format ")] 144 | [ValidateNotNullOrEmpty()] 145 | [Security.SecureString]$AdminPwd, 146 | 147 | [parameter(Mandatory=$true, 148 | ParameterSetName = 'UsingCSV', 149 | HelpMessage="Enter full path to CSV file with list of Dell service tags ")] 150 | [ValidateNotNullOrEmpty()] 151 | [string]$InputCSV, 152 | 153 | [parameter(Mandatory=$false, 154 | HelpMessage="Enter output directory for warranty details ")] 155 | [ValidateNotNullOrEmpty()] 156 | [string]$OutputDir, 157 | 158 | [parameter(Mandatory=$false, 159 | HelpMessage="Enter optional filter e.g. WarrantyExpiringIn30Days. ` 160 | Default: AnyWarranty ")] 161 | [ValidateNotNullOrEmpty()] 162 | [ValidateSet("ActiveWarranty", "ExpiredWarranty", "WarrantyExpiringIn30Days")] 163 | [string]$Filter, 164 | 165 | [parameter(Mandatory=$false, 166 | HelpMessage="Enter the Proxy Server to use custom proxy settings. ` 167 | / ")] 168 | [ValidateNotNullOrEmpty()] 169 | [string]$ProxyServer, 170 | 171 | [parameter(Mandatory=$false, 172 | HelpMessage="Enter the Proxy Port. e.g. 80 ")] 173 | [ValidateNotNullOrEmpty()] 174 | [int]$ProxyPort, 175 | 176 | [parameter(Mandatory=$false, 177 | HelpMessage="Enter the Proxy User Name. ")] 178 | [ValidateNotNullOrEmpty()] 179 | [string]$ProxyUser, 180 | 181 | [parameter(Mandatory=$false, 182 | HelpMessage="Enter the Proxy Password in a SecureString format. ")] 183 | [ValidateNotNullOrEmpty()] 184 | [SecureString]$ProxyPassword 185 | ) 186 | 187 | try 188 | { 189 | # ** Pre-requisite validation. *** 190 | 191 | $ProgramFilesx86Path = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)") 192 | $DCWPath = Join-Path $ProgramFilesx86Path -ChildPath "Dell" ` 193 | | Join-Path -ChildPath "CommandIntegrationSuite" ` 194 | | Join-Path -ChildPath "DellWarranty-CLI.exe" 195 | 196 | if (-not(Test-Path $DCWPath)) 197 | { 198 | Write-Error "Dell Command | Warranty is not installed. ` 199 | Please retry after installation." 200 | exit(1) 201 | } 202 | 203 | # ** Input validation. *** 204 | 205 | If (-not((-not($ProxyServer) -and -not($ProxyPort) -and -not($ProxyUser) -and -not($ProxyPassword)) -or 206 | ($ProxyServer -and $ProxyPort -and -not($ProxyUser) -and -not($ProxyPassword)) -or 207 | ($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword) 208 | )) 209 | { 210 | Write-Error "Mandatory proxy arguments missing" 211 | exit(1) 212 | } 213 | 214 | If(-not($OutputDir)) 215 | { 216 | $OutputDir = $PSScriptRoot 217 | } 218 | 219 | If(-not(Test-Path -Path $OutputDir)) 220 | { 221 | Try 222 | { 223 | Write-Host Creating output directory: $OutputDir `n 224 | New-Item -Path $OutputDir -ItemType Directory -Force | Out-Null 225 | 226 | # Apply ACL 227 | 228 | Write-Host Applying ACL to Folder: $OutputDir `n 229 | $ACL = Get-Item $OutputDir | get-acl 230 | # Remove inheritance 231 | $ACL.SetAccessRuleProtection($true,$true) 232 | $ACL | Set-Acl 233 | # Remove Users 234 | $accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("users","Read",,,"Allow") 235 | $ACL.RemoveAccessRuleAll($accessrule) 236 | Set-Acl -Path $OutputDir -AclObject $ACL 237 | } 238 | Catch 239 | { 240 | Write-Host Error creating output directory $OutputDir `n 241 | Write-Error "$($_.Exception)" 242 | exit(1) 243 | } 244 | } 245 | else 246 | { 247 | $OutputDirObj = Get-Item $OutputDir -Force -ea SilentlyContinue 248 | if([bool]($OutputDirObj.Attributes -band [IO.FileAttributes]::ReparsePoint)) 249 | { 250 | Write-Error "Directory reparse point exists for $OutputDir. ` 251 | Select another directory and retry... " 252 | exit(1) 253 | } 254 | } 255 | 256 | $InputCSVFilePath = $InputCSV 257 | 258 | If($InputCSVFilePath) 259 | { 260 | if(-not(Test-Path -Path $InputCSVFilePath -PathType Leaf)) 261 | { 262 | Write-Error "Input CSV file not found" 263 | exit(1) 264 | } 265 | } 266 | else 267 | { 268 | $RemoveModule = $false 269 | 270 | # Prepare the input filename 271 | 272 | $FileName = "Input.csv" 273 | $FileTimeStamp = (get-date -format yyyyMMdd_HHmmss) + "_" + $FileName 274 | $FilePath = Join-Path $PSScriptRoot -ChildPath $FileTimeStamp 275 | Write-Host "FilePath: $FilePath" 276 | 277 | # Install the PowerShell module for Microsoft Graph from PS gallery. 278 | 279 | if (Get-Module -ListAvailable -Name "Microsoft.Graph.Intune") 280 | { 281 | Write-Host "Microsoft.Graph.Intune PowerShell module exists" 282 | } 283 | else 284 | { 285 | # MIT License 286 | # https://www.powershellgallery.com/packages/Microsoft.Graph.Intune/6.1907.1.0/Content/LICENSE.txt 287 | Install-Module -Name Microsoft.Graph.Intune ` 288 | -Repository PSGallery ` 289 | -AllowClobber ` 290 | -Scope CurrentUser ` 291 | -Force ` 292 | -ErrorAction stop 293 | 294 | $RemoveModule = $true 295 | } 296 | 297 | # Verify Installation 298 | 299 | If (-not(Get-InstalledModule Microsoft.Graph.Intune -ErrorAction silentlycontinue)) 300 | { 301 | Write-Error "Microsoft.Graph.Intune PowerShell module installation failed" 302 | exit(1) 303 | } 304 | 305 | # Import the Microsoft.Graph.Intune module 306 | Import-Module Microsoft.Graph.Intune -ErrorAction SilentlyContinue 307 | 308 | # Authenticate with Microsoft Graph. 309 | # Create the PSCredential object. 310 | 311 | $AdminCred = New-Object System.Management.Automation.PSCredential ($adminUPN, $adminPwd) 312 | 313 | # Log in with these credentials 314 | Connect-MSGraph -PSCredential $AdminCred | Out-Null 315 | 316 | 317 | # Retrieve list of device serial number. 318 | 319 | #$ServiceTags = Get-IntuneManagedDevice -Filter "startswith(deviceName,'DELL_')" | | Select-Object -Property serialNumber 320 | $ServiceTags = Get-IntuneManagedDevice | Select-Object -Property serialNumber 321 | 322 | if($RemoveModule -eq $true) 323 | { 324 | Write-Host "Removing Microsoft.Graph.Intune module" 325 | Remove-Module -Name Microsoft.Graph.Intune -Force 326 | } 327 | 328 | [System.Collections.ArrayList]$ValidServiceTags = @() 329 | foreach ($serviceTag in $ServiceTags) 330 | { 331 | if (($serviceTag.serialNumber -ne "") ` 332 | -and ($null -ne $serviceTag.serialNumber) ` 333 | -and ($serviceTag.serialNumber -match '.*\b[A-Z\d]{7}\b.*')) 334 | { 335 | [void]$ValidServiceTags.Add($serviceTag.serialNumber) 336 | } 337 | } 338 | 339 | $ValidServiceTags | Out-File $FilePath 340 | $InputCSVFilePath = $FilePath 341 | } 342 | 343 | 344 | # Prepare the output filename 345 | 346 | $OutputCSVFileName = "WarrantyOutput.csv" 347 | $FileTimeStamp = (get-date -format yyyyMMdd_HHmmss) + "_" + $OutputCSVFileName 348 | $OutputCSVFilePath = Join-Path $OutputDir -ChildPath $FileTimeStamp 349 | 350 | 351 | 352 | # Create the list of arguments to invoke Dell Command | Warranty 353 | 354 | $OptionalArguments = " " 355 | 356 | if($Filter) 357 | { 358 | $OptionalArguments = $OptionalArguments + " /F=" + $Filter 359 | } 360 | 361 | if($ProxyServer -and $ProxyPort) 362 | { 363 | $ProxyServerPort = $ProxyServer.Trim() + ":" + $ProxyPort 364 | $OptionalArguments = $OptionalArguments + " /Ps=" + $ProxyServerPort 365 | } 366 | 367 | if($ProxyUser -and $ProxyPassword) 368 | { 369 | $UnsecureProxyPassword = [System.Net.NetworkCredential]::new("", $ProxyPassword).Password 370 | $OptionalArguments = $OptionalArguments + " /Pu=" + $ProxyUser + " /Pd=" + $UnsecureProxyPassword 371 | } 372 | 373 | $arglist = @((" /I=" + $InputCSVFilePath + " /E=" + $OutputCSVFilePath + $OptionalArguments )) 374 | 375 | # Invoke Dell Command | Warranty 376 | 377 | Start-Process -FilePath $DCWPath -ArgumentList $arglist -WindowStyle Hidden 378 | 379 | } 380 | Catch 381 | { 382 | $Exception = $_ 383 | Write-Error "Exception:" $Exception 384 | } 385 | Finally 386 | { 387 | Write-Host "Function Get-DellWarrantyInBulk Executed" 388 | Write-Host "Observe Dell | Command Warranty log files for more information" 389 | } 390 | } 391 | 392 | 393 | 394 | 395 | -------------------------------------------------------------------------------- /Intune Scripts/Update/Dell_Download_Driver_Files.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Supreeth Dayananda 3 | _version_ = 1.0 4 | 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | #> 17 | 18 | <# 19 | .Synopsis 20 | Get-DellDriverPack cmdlet used to retrieve the driver pack for the individual system. 21 | This script can be used by an administrative user to download all the drivers for a particular system that can be later deployed to that system. 22 | IMPORTANT: Make sure you are using latest PowerShell version 5 or newer to execute this cmdlet. Execute "Get-Host" to check the version. 23 | .DESCRIPTION 24 | Cmdlet used to retrieve driver pack for the individual system that is applicable and can installed for that particular system. 25 | - SystemID, REQUIRED, the Platform System ID or BIOS ID of the system for which the drivers must be downloaded. 26 | Note: System ID can be found under System Information -> System Summary -> System SKU (System ID or BIOS ID) 27 | win + R, type msinfo32 to get the System Information. Under System Information look for System SKU. 28 | PowerShell Command to get the Platform System ID or BIOS ID of the system - 29 | (Get-CimInstance Win32_ComputerSystem).SystemSKUNumber 30 | - SystemOS, REQUIRED, the target Operating System on which the drivers will be installed. 31 | - DownloadDir, REQUIRED, the download path where all the driver files will be downloaded. 32 | - ProxyServer, OPTIONAL, the custom proxy server address. 33 | - ProxyPort, OPTIONAL, the custom proxy server port. 34 | - ProxyUser, OPTIONAL, the custom proxy Username. 35 | - ProxyPassword, OPTIONAL, the custom Proxy Password 36 | The ProxyPassword is a SecureString parameter, user must convert to SecureString before passing the ProxyPassword parameter to 37 | Get-DellDriverPack cmdlet. 38 | e.g. $ProxyPass = "Password" 39 | $SecureProxyPassword = ConvertTo-SecureString $ProxyPass -AsPlainText -Force 40 | 41 | .EXAMPLE 42 | This example shows how to download the Driver packages using SystemID, System-OS and Download-Directory 43 | Get-DellDriverFiles -SystemID "0A40" -SystemOS "Windows 10 x64" -DownloadDir "LocalPath" 44 | .EXAMPLE 45 | This example shows how to download the Driver packages using the custom proxy settings 46 | Get-DellDriverFiles -SystemID "0A40" -SystemOS "Win 10 x64" -DownloadDir "LocalPath" -ProxyServer "http://" -ProxyPort "80" 47 | .EXAMPLE 48 | This example shows how to download the Driver packages using the custom proxy settings using user credentials 49 | $ProxyPass = "Password" 50 | $SecureProxyPassword = ConvertTo-SecureString $ProxyPass -AsPlainText -Force 51 | Get-DellDriverFiles -SystemID "0A40" -SystemOS "Win 10 x64" -DownloadDir "LocalPath" -ProxyServer "http://" -ProxyPort "80" -ProxyUser "Username" -ProxyPassword $SecureProxyPassword 52 | #> 53 | 54 | Function Get-DellDriverFiles 55 | { 56 | param( 57 | [parameter(Mandatory=$true, HelpMessage="Enter target System ID or BIOS ID for which the drivers must be downloaded. e.g. 0A40 ")] 58 | [ValidateNotNullOrEmpty()] 59 | [string]$SystemID, 60 | 61 | [parameter(Mandatory=$true, HelpMessage="Enter the target Operating System on which the drivers will be installed. e.g. Windows 11 x64")] 62 | [ValidateNotNullOrEmpty()] 63 | [ValidateSet("Windows 10 x64", "Windows 11 x64")] 64 | [string]$SystemOS, 65 | 66 | [parameter(Mandatory=$true, HelpMessage="Enter the download folder location where the files will be downloaded. ")] 67 | [ValidateNotNullOrEmpty()] 68 | [string]$DownloadDir, 69 | 70 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy Server to use custom proxy settings. e.g. http:// ")] 71 | [ValidateNotNullOrEmpty()] 72 | [string]$ProxyServer, 73 | 74 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy Port. e.g. 80 ")] 75 | [ValidateNotNullOrEmpty()] 76 | [int]$ProxyPort, 77 | 78 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy User Name. ")] 79 | [ValidateNotNullOrEmpty()] 80 | [string]$ProxyUser, 81 | 82 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy Password. ")] 83 | [ValidateNotNullOrEmpty()] 84 | [SecureString]$ProxyPassword 85 | 86 | ) 87 | 88 | try 89 | { 90 | 91 | # ** Mandatory Proxy Arguments Validation. *** 92 | 93 | If(!((!$ProxyServer -and !$ProxyPort -and !$ProxyUser -and !$ProxyPassword) -or 94 | ($ProxyServer -and $ProxyPort -and !$ProxyUser -and !$ProxyPassword) -or 95 | ($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword))) 96 | { 97 | Write-Host Error: Missing Mandatory Proxy Arguments `n -BackgroundColor Red 98 | exit(1) 99 | } 100 | 101 | # DriverCabCatalog File Name 102 | $DriverCabCatalogFileName = "DriverPackCatalog.cab" 103 | # DriverCabCatalog XML File Name 104 | $DriverCabCatalogXMLFileName = "DriverPackCatalog.xml" 105 | # DriverPackCatalog.cab file URL 106 | $DriverCabCatalog = "https://downloads.dell.com/catalog/DriverPackCatalog.cab" 107 | # Download directory name (System_ID_System_OS) 108 | $DownloadDirName = $SystemID.Trim() + " " + $SystemOS.Trim() 109 | $DownloadDirName = $DownloadDirName.Replace(" ","_") 110 | # Download folder path 111 | $DriverDownloadFolder = Join-Path -Path $DownloadDir -ChildPath $DownloadDirName 112 | # DriverPackCatalog.cab download path 113 | $DriverCabCatalogFile = Join-Path -Path $DriverDownloadFolder -ChildPath $DriverCabCatalogFileName 114 | # DriverPackCatalog.xml extraction path 115 | $DriverCatalogXMLFile = Join-Path -Path $DriverDownloadFolder -ChildPath $DriverCabCatalogXMLFileName 116 | 117 | # *** Check if download directory exists, if it does not exist create download directory *** 118 | Try 119 | { 120 | $DownloadDir = Resolve-Path -Path $DownloadDir 121 | } 122 | Catch 123 | { 124 | Write-Host Error resolving path $DownloadDir `n 125 | Write-Error "$($_.Exception)" 126 | Try 127 | { 128 | Write-Host Creating Download Directory: $DownloadDir `n 129 | New-Item -Path $DownloadDir -ItemType Directory -Force | Out-Null 130 | } 131 | Catch 132 | { 133 | Write-Host Error creating download directory $DownloadDir `n 134 | Write-Error "$($_.Exception)" 135 | exit(1) 136 | } 137 | } 138 | If(!(Test-Path -Path $DownloadDir)) 139 | { 140 | Try 141 | { 142 | Write-Host Creating Download Directory: $DownloadDir `n 143 | New-Item -Path $DownloadDir -ItemType Directory -Force | Out-Null 144 | } 145 | Catch 146 | { 147 | Write-Host Error creating download directory $DownloadDir `n 148 | Write-Error "$($_.Exception)" 149 | exit(1) 150 | } 151 | } 152 | else 153 | { 154 | $DownloadDirFile = Get-Item $DownloadDir -Force -ea SilentlyContinue 155 | if([bool]($DownloadDirFile.Attributes -band [IO.FileAttributes]::ReparsePoint)) 156 | { 157 | Write-Host "Directory Reparse Point Exists for $DownloadDir. Select another directory and re-run script..." `n -BackgroundColor Red 158 | exit(1) 159 | } 160 | } 161 | 162 | # *** If the System_Model_System_OS folder exists in the Download directory, delete the folder. *** 163 | 164 | If(Test-Path -Path $DriverDownloadFolder) 165 | { 166 | Try 167 | { 168 | Write-Host Deleting Folder: $DriverDownloadFolder `n 169 | Remove-Item -Path $DriverDownloadFolder -Recurse -Force | Out-Null 170 | } 171 | Catch 172 | { 173 | Write-Host Error deleting directory $DriverDownloadFolder `n 174 | Write-Error "$($_.Exception)" 175 | exit(1) 176 | } 177 | } 178 | 179 | # *** Create System_Model_System_OS folder under Download directory. *** 180 | 181 | Try 182 | { 183 | Write-Host Creating Folder: $DriverDownloadFolder `n 184 | 185 | New-Item -Path $DriverDownloadFolder -ItemType Directory -Force | Out-Null 186 | 187 | # Apply ACL 188 | 189 | Write-Host Applying ACL to Folder: $DriverDownloadFolder `n 190 | 191 | $ACL = Get-Item $DriverDownloadFolder | get-acl 192 | # Remove inheritance 193 | $ACL.SetAccessRuleProtection($true,$true) 194 | $ACL | Set-Acl 195 | # Remove Users 196 | $accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("users","Read",,,"Allow") 197 | $ACL.RemoveAccessRuleAll($accessrule) 198 | Set-Acl -Path $DriverDownloadFolder -AclObject $ACL 199 | } 200 | Catch 201 | { 202 | Write-Host Error creating directory $DriverDownloadFolder `n 203 | Write-Error "$($_.Exception)" 204 | exit(1) 205 | } 206 | 207 | 208 | # *** To Download the Driver Cab Catalog. *** 209 | 210 | try { 211 | Write-Host Downloading DriverPackCatalog file... `n 212 | $WebClient = New-Object -TypeName System.Net.WebClient 213 | # *** Check if Custom Proxy Settings is passed and set the custom proxy settings. *** 214 | if($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword) 215 | { 216 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 217 | Write-Host Downloading DriverPackCatalog File using Custom Proxy Settings using Proxy Credentials. `n 218 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 219 | $WebProxyCredentials = (New-Object Net.NetworkCredential($ProxyUser.Trim(),$ProxyPassword)).GetCredential($ProxyServer.Trim(),$ProxyPort,"KERBEROS") 220 | $WebProxy.Credentials = $WebProxyCredentials 221 | $WebClient.Proxy = $WebProxy 222 | } 223 | elseif($ProxyServer -and $ProxyPort) 224 | { 225 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 226 | Write-Host Downloading DriverPackCatalog File using Custom Proxy Settings. `n 227 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 228 | $WebClient.Proxy = $WebProxy 229 | } 230 | 231 | $WebClient.DownloadFile($DriverCabCatalog, "$DriverCabCatalogFile") 232 | 233 | if (Test-Path "$DriverCabCatalogFile") 234 | { 235 | Write-Host DriverPackCatalog file downloaded successful. `n 236 | } 237 | else 238 | { 239 | Write-Host DriverPackCatalog file is not downloaded! `n -BackgroundColor Red 240 | exit(1) 241 | } 242 | } 243 | catch [System.Net.WebException] 244 | { 245 | Write-Error "$($_.Exception)" 246 | exit(1) 247 | } 248 | 249 | 250 | # *** To Extract the DriverPackCatalog file. *** 251 | 252 | try { 253 | Write-Host Extracting DriverPackCatalog file... `n 254 | expand -r $DriverCabCatalogFile $DriverDownloadFolder 255 | if (Test-Path "$DriverCatalogXMLFile") 256 | { 257 | Write-Host DriverPackCatalog file extraction successful. `n 258 | } 259 | else 260 | { 261 | Write-Host DriverPackCatalog XML file extraction failed! `n -BackgroundColor Red 262 | exit(1) 263 | } 264 | } 265 | catch [Exception] 266 | { 267 | Write-Error "$($_.Exception)" 268 | exit(1) 269 | } 270 | 271 | try { 272 | [xml]$CatalogXML = Get-Content -Path $DriverCatalogXMLFile -ErrorAction Ignore 273 | [array]$DriverPackages = $CatalogXML.DriverPackManifest.DriverPackage 274 | $urlBase = "https://downloads.dell.com/" 275 | $NoDriverMatchFound = $true 276 | foreach ($DriverPackage in $DriverPackages) 277 | { 278 | # Driver Package Name 279 | $DriverPackageName = $DriverPackage.Name.Display.'#cdata-section'.Trim() 280 | # Driver Match Found Flag 281 | $DriverMatchFound = $false 282 | # Driver Download url 283 | $DriverDownloadPath = -join($urlBase, $DriverPackage.path) 284 | # Driver Download Path 285 | $DriverDownloadDestPath = -join($DriverDownloadFolder,"\$DriverPackageName") 286 | 287 | foreach ($SupportedSystems in $DriverPackage.SupportedSystems.Brand) 288 | { 289 | $SystemIDFromCatalog = $SupportedSystems.Model.systemID 290 | 291 | # Check for System ID Match 292 | if ($SystemIDFromCatalog -eq $SystemID) 293 | { 294 | # Check for System OS Match 295 | foreach ($SupportedOS in $DriverPackage.SupportedOperatingSystems) 296 | { 297 | if ($SupportedOS.OperatingSystem.Display.'#cdata-section'.Trim() -match $SystemOS) 298 | { 299 | $NoDriverMatchFound = $false 300 | $DriverMatchFound = $true 301 | } 302 | } 303 | } 304 | } 305 | 306 | # *** Download the driver if both System ID and System OS match found. *** 307 | 308 | if ($DriverMatchFound) 309 | { 310 | Write-Host Downloading driver file! `n The download might take some time... `n Make sure the internet is not disconnected! `n -BackgroundColor Gray 311 | # Adding stopwatch to get the total time taken to download the driver. 312 | $StopWatch = [system.diagnostics.stopwatch]::StartNew() 313 | $WebClient = New-Object -TypeName System.Net.WebClient 314 | 315 | # *** Check if Custom Proxy Settings is passed and set the custom proxy settings. *** 316 | if($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword) 317 | { 318 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 319 | Write-Host Downloading Driver using Custom Proxy Settings using Proxy Credentials. `n 320 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 321 | $WebProxyCredentials = (New-Object Net.NetworkCredential($ProxyUser.Trim(),$ProxyPassword)).GetCredential($ProxyServer.Trim(),$ProxyPort,"KERBEROS") 322 | $WebProxy.Credentials = $WebProxyCredentials 323 | $WebClient.Proxy = $WebProxy 324 | } 325 | elseif($ProxyServer -and $ProxyPort) 326 | { 327 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 328 | Write-Host Downloading Driver using Custom Proxy Settings. `n 329 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 330 | $WebClient.Proxy = $WebProxy 331 | } 332 | 333 | $WebClient.DownloadFile($DriverDownloadPath, $DriverDownloadDestPath) 334 | $StopWatch.Stop() 335 | $TotalDriverDownloadTime = $StopWatch.Elapsed 336 | 337 | # *** Once Driver Download is completed Check if the SHA256 hash matches with the downloaded driver. *** 338 | if (Test-Path "$DriverDownloadDestPath") 339 | { 340 | Write-Host "Driver download successful: $DriverPackageName `n" 341 | Write-Host "Total time taken to download driver $DriverPackageName (hh:mm:ss.ms): $TotalDriverDownloadTime `n" 342 | # MD5 hash from the xml file 343 | $MD5Hash = $DriverPackage.Cryptography.Hash | Where-Object { $_.algorithm -eq 'SHA256' } | Select-Object -ExpandProperty "#text" 344 | # MD5 hash of the downloaded driver file 345 | $DriverFileMD5Hash = Get-FileHash $DriverDownloadDestPath -Algorithm SHA256 346 | if($MD5Hash -eq $DriverFileMD5Hash.Hash) 347 | { 348 | Write-Host "MD5 hash match successful - $DriverPackageName. `n" 349 | } 350 | else 351 | { 352 | Write-Host "MD5 has match failed. Hence, deleting the driver file $DriverPackageName. `n" 353 | Remove-Item -Path $DriverDownloadDestPath -Recurse -Force | Out-Null 354 | } 355 | } 356 | else 357 | { 358 | Write-Host "Driver download failed: $DriverPackageName `n" 359 | } 360 | 361 | } 362 | 363 | } 364 | 365 | if($NoDriverMatchFound -eq $true) 366 | { 367 | Write-Host "No Driver Match found for the SystemID: $SystemID, OS: $SystemOS. `n" 368 | Write-Host "Contact Dell Support. `n" 369 | } 370 | 371 | } 372 | catch [Exception] 373 | { 374 | Write-Error "$($_.Exception)" 375 | } 376 | 377 | } 378 | catch 379 | { 380 | Write-Error "$($_.Exception)" 381 | } 382 | Finally 383 | { 384 | # Delete DriverPackCatalog.cab file 385 | if($DriverCabCatalogFile) 386 | { 387 | if(Test-Path $DriverCabCatalogFile) 388 | { 389 | Remove-Item -Path $DriverCabCatalogFile -Recurse -Force | Out-Null 390 | } 391 | } 392 | # Delete DriverPackCatalog.xml file 393 | if($DriverCatalogXMLFile) 394 | { 395 | if(Test-Path $DriverCatalogXMLFile) 396 | { 397 | Remove-Item -Path $DriverCatalogXMLFile -Recurse -Force | Out-Null 398 | } 399 | } 400 | Write-Host "Function Get-DellDriverFiles Executed" 401 | } 402 | } 403 | 404 | -------------------------------------------------------------------------------- /Intune Scripts/Update/Dell_Install_Driver_Files.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | _author_ = Supreeth Dayananda 3 | _version_ = 1.0 4 | 5 | Copyright © 2023 Dell Inc. or its subsidiaries. All Rights Reserved. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | #> 17 | 18 | <# 19 | .Synopsis 20 | Install-DellDriverFiles cmdlet used to download and install the driver pack for the individual system. 21 | This script can be used by an administrative user to download and install all the drivers for a particular system. 22 | IMPORTANT: Make sure you are using latest PowerShell version 5 or newer to execute this cmdlet. Execute "Get-Host" to check the version. 23 | IMPORTANT: Make sure to run this script in 64-bit PowerShell Host only. As PNPUtil command to install drivers is supported only on 64-bit. 24 | While deploying the script via Intune, make sure to select "Yes" - "Run Script in 64-bit PowerShell Host". 25 | .DESCRIPTION 26 | Cmdlet used to download and install driver pack for the individual system. 27 | - DownloadDir, REQUIRED, the download path where all the driver files will be downloaded and installed from. 28 | - Restart, OPTIONAL, pass in -Restart switch if local system restart needs to be performed after driver installation (recommended) 29 | - ProxyServer, OPTIONAL, the custom proxy server address. 30 | - ProxyPort, OPTIONAL, the custom proxy server port. 31 | - ProxyUser, OPTIONAL, the custom proxy Username. 32 | - ProxyPassword, OPTIONAL, the custom Proxy Password 33 | The ProxyPassword is a SecureString parameter, user must convert to SecureString before passing the ProxyPassword parameter to 34 | Install-DellDriverFiles cmdlet. 35 | e.g. $ProxyPass = "Password" 36 | $SecureProxyPassword = ConvertTo-SecureString $ProxyPass -AsPlainText -Force 37 | NOTE: 38 | 1. This Script will create a Log File - "DellDriverInstaller_Log.txt" under the DownloadDir to track the driver installation data. 39 | 40 | .EXAMPLE 41 | This example shows how to download and install the Driver packages using Download-Directory 42 | Install-DellDriverFiles -DownloadDir "LocalPath" 43 | .EXAMPLE 44 | This example shows how to download and install the Driver packages using Download-Directory and restart switch 45 | Install-DellDriverFiles -DownloadDir "LocalPath" -Restart 46 | .EXAMPLE 47 | This example shows how to download and install the Driver packages using the custom proxy settings 48 | Install-DellDriverFiles -DownloadDir "LocalPath" -ProxyServer "http://" -ProxyPort "80" 49 | .EXAMPLE 50 | This example shows how to download and install the Driver packages using the custom proxy settings using user credentials 51 | $ProxyPass = "Password" 52 | $SecureProxyPassword = ConvertTo-SecureString $ProxyPass -AsPlainText -Force 53 | Install-DellDriverFiles -DownloadDir "LocalPath" -ProxyServer "http://" -ProxyPort "80" -ProxyUser "Username" -ProxyPassword $SecureProxyPassword 54 | #> 55 | 56 | Function Restart-DellComputer 57 | { 58 | param( 59 | [parameter(Mandatory=$true, HelpMessage="Enter time in seconds")] 60 | [ValidateNotNullOrEmpty()] 61 | [int]$Seconds 62 | ) 63 | try 64 | { 65 | Write-Host "Following will happen during restart" 66 | $WhatIf = Restart-Computer -WhatIf 67 | Write-Host $WhatIf 68 | 69 | Write-Host "Waiting for" $Seconds "before restart" 70 | Start-Sleep -Seconds $Seconds 71 | Write-Host "Attempting system restart at " $(Get-Date) -EA stop 72 | 73 | Restart-Computer -ComputerName . -Force -EA stop 74 | } 75 | catch [Exception] 76 | { 77 | Write-Error "$($_.Exception)" 78 | } 79 | finally 80 | { 81 | Write-Host "Restart-DellComputer Executed" 82 | } 83 | } 84 | 85 | Function Install-DellDriverFiles 86 | { 87 | param( 88 | [parameter(Mandatory=$true, HelpMessage="Enter the download folder location where the files will be downloaded. ")] 89 | [ValidateNotNullOrEmpty()] 90 | [string]$DownloadDir, 91 | 92 | [parameter(Mandatory=$false, HelpMessage="use -Restart switch if system Restart needs to be performed")] 93 | [switch]$Restart, 94 | 95 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy Server to use custom proxy settings. e.g. http:// ")] 96 | [ValidateNotNullOrEmpty()] 97 | [string]$ProxyServer, 98 | 99 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy Port. e.g. 80 ")] 100 | [ValidateNotNullOrEmpty()] 101 | [int]$ProxyPort, 102 | 103 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy User Name. ")] 104 | [ValidateNotNullOrEmpty()] 105 | [string]$ProxyUser, 106 | 107 | [parameter(Mandatory=$false, HelpMessage="Enter the Proxy Password. ")] 108 | [ValidateNotNullOrEmpty()] 109 | [SecureString]$ProxyPassword 110 | 111 | ) 112 | 113 | try 114 | { 115 | # ** If PowerShell process is running as 32-bit process exit the script, as PNPUtil is supported only as 64-bit process. 116 | 117 | if(![Environment]::Is64BitProcess) 118 | { 119 | Write-Host Error: Script is not supported in 32-bit PowerShell Host `n -BackgroundColor Red 120 | Write-Host Run Script in 64-bit PowerShell Host `n -BackgroundColor Red 121 | exit(1) 122 | } 123 | 124 | # ** Mandatory Proxy Arguments Validation. *** 125 | 126 | If(!((!$ProxyServer -and !$ProxyPort -and !$ProxyUser -and !$ProxyPassword) -or 127 | ($ProxyServer -and $ProxyPort -and !$ProxyUser -and !$ProxyPassword) -or 128 | ($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword))) 129 | { 130 | Write-Host Error: Missing Mandatory Proxy Arguments `n -BackgroundColor Red 131 | exit(1) 132 | } 133 | # Driver installation status flag 134 | $DriverInstallSuccess = $false 135 | # To get the current date and time to write onto log-file. 136 | $Date = Get-Date 137 | # DriverCabCatalog File Name 138 | $DriverCabCatalogFileName = "DriverPackCatalog.cab" 139 | # DriverCabCatalog XML File Name 140 | $DriverCabCatalogXMLFileName = "DriverPackCatalog.xml" 141 | # DriverPackCatalog.cab file URL 142 | $DriverCabCatalog = "https://downloads.dell.com/catalog/DriverPackCatalog.cab" 143 | # Platform System ID or BIOS ID 144 | $SystemID = (Get-CimInstance Win32_ComputerSystem).SystemSKUNumber 145 | # Platform System OS 146 | $PlatformSystemOS = (Get-CimInstance Win32_OperatingSystem).Caption 147 | #Platform OS Architecture 148 | $PlatformSystemOSArch = [Environment]::Is64BitOperatingSystem 149 | # Check OS architecture, supports only 64-bit architecture 150 | if($PlatformSystemOSArch -ne "True") 151 | { 152 | Write-Host Error: Supports only 64-bit architecture! `n -BackgroundColor Red 153 | exit(1) 154 | } 155 | 156 | # Supported for only Windows 10 and Windows 11 OS 157 | if($PlatformSystemOS -match "Windows 10") 158 | { 159 | $SystemOS = "Windows 10 x64" 160 | } 161 | elseif($PlatformSystemOS -match "Windows 11") 162 | { 163 | $SystemOS = "Windows 11 x64" 164 | } 165 | else 166 | { 167 | Write-Host Error: Supports only Windows 10 and Windows 11 platforms `n -BackgroundColor Red 168 | exit(1) 169 | } 170 | 171 | # Download directory name (System_ID_System_OS) 172 | $DownloadDirName = $SystemID.Trim() + " " + $SystemOS.Trim() 173 | $DownloadDirName = $DownloadDirName.Replace(" ","_") 174 | # Download folder path 175 | $DriverDownloadFolder = Join-Path -Path $DownloadDir -ChildPath $DownloadDirName 176 | # DriverPackCatalog.cab download path 177 | $DriverCabCatalogFile = Join-Path -Path $DriverDownloadFolder -ChildPath $DriverCabCatalogFileName 178 | # DriverPackCatalog.xml extraction path 179 | $DriverCatalogXMLFile = Join-Path -Path $DriverDownloadFolder -ChildPath $DriverCabCatalogXMLFileName 180 | # Log-File Path 181 | $LogFileName = "DellDriverInstaller_Log.txt" 182 | $LogFilePath = Join-Path -Path $DriverDownloadFolder -ChildPath $LogFileName 183 | 184 | # *** Check if download directory exists, if it does not exist create download directory *** 185 | Try 186 | { 187 | $DownloadDir = Resolve-Path -Path $DownloadDir 188 | } 189 | Catch [Exception] 190 | { 191 | Write-Host Error resolving path $DownloadDir `n 192 | Write-Error "$($_.Exception)" 193 | Try 194 | { 195 | Write-Host Creating Download Directory: $DownloadDir `n 196 | New-Item -Path $DownloadDir -ItemType Directory -Force | Out-Null 197 | } 198 | Catch [Exception] 199 | { 200 | Write-Host Error creating download directory $DownloadDir `n 201 | Write-Error "$($_.Exception)" 202 | exit(1) 203 | } 204 | } 205 | If(!(Test-Path -Path $DownloadDir)) 206 | { 207 | Try 208 | { 209 | Write-Host Creating Download Directory: $DownloadDir `n 210 | New-Item -Path $DownloadDir -ItemType Directory -Force | Out-Null 211 | } 212 | Catch [Exception] 213 | { 214 | Write-Host Error creating download directory $DownloadDir `n 215 | Write-Error "$($_.Exception)" 216 | exit(1) 217 | } 218 | } 219 | else 220 | { 221 | $DownloadDirFile = Get-Item $DownloadDir -Force -ea SilentlyContinue 222 | if([bool]($DownloadDirFile.Attributes -band [IO.FileAttributes]::ReparsePoint)) 223 | { 224 | Write-Host "Directory Reparse Point Exists for $DownloadDir. Select another directory and re-run script..." `n -BackgroundColor Red 225 | exit(1) 226 | } 227 | } 228 | 229 | # *** If the System_Model_System_OS folder exists in the Download directory, delete the folder. *** 230 | 231 | If(Test-Path -Path $DriverDownloadFolder) 232 | { 233 | Try 234 | { 235 | Write-Host Deleting Folder: $DriverDownloadFolder `n 236 | Remove-Item -Path $DriverDownloadFolder -Recurse -Force | Out-Null 237 | } 238 | Catch [Exception] 239 | { 240 | Write-Host Error deleting directory $DriverDownloadFolder `n 241 | Write-Error "$($_.Exception)" 242 | exit(1) 243 | } 244 | } 245 | 246 | # *** Create System_Model_System_OS folder under Download directory. *** 247 | 248 | Try 249 | { 250 | Write-Host Creating Folder: $DriverDownloadFolder `n 251 | 252 | New-Item -Path $DriverDownloadFolder -ItemType Directory -Force | Out-Null 253 | 254 | # Apply ACL 255 | 256 | Write-Host Applying ACL to Folder: $DriverDownloadFolder `n 257 | 258 | $ACL = Get-Item $DriverDownloadFolder | get-acl 259 | # Remove inheritance 260 | $ACL.SetAccessRuleProtection($true,$true) 261 | $ACL | Set-Acl 262 | # Remove Users 263 | $accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("users","Read",,,"Allow") 264 | $ACL.RemoveAccessRuleAll($accessrule) 265 | Set-Acl -Path $DriverDownloadFolder -AclObject $ACL 266 | # Create Log File 267 | New-Item -ItemType File -Path $LogFilePath -Force 268 | } 269 | Catch [Exception] 270 | { 271 | Write-Host Error creating directory $DriverDownloadFolder `n 272 | Write-Error "$($_.Exception)" 273 | exit(1) 274 | } 275 | 276 | # *** Adding contents into Log-File. *** 277 | 278 | Add-Content -Path $LogFilePath -Value "====================================" 279 | 280 | Add-Content -Path $LogFilePath -Value " Script - Dell_Install_Driver_Files.ps1 " 281 | 282 | Add-Content -Path $LogFilePath -Value " $Date " 283 | 284 | Add-Content -Path $LogFilePath -Value " System ID - $SystemID " 285 | 286 | Add-Content -Path $LogFilePath -Value " System OS - $SystemOS " 287 | 288 | Add-Content -Path $LogFilePath -Value "====================================" 289 | 290 | 291 | # *** To Download the Driver Cab Catalog. *** 292 | 293 | try { 294 | Write-Host Downloading DriverPackCatalog file... `n 295 | Add-Content -Path $LogFilePath -Value "Downloading DriverPackCatalog file..." 296 | $WebClient = New-Object -TypeName System.Net.WebClient 297 | # *** Check if Custom Proxy Settings is passed and set the custom proxy settings. *** 298 | if($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword) 299 | { 300 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 301 | Write-Host Downloading DriverPackCatalog File using Custom Proxy Settings using Proxy Credentials. `n 302 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 303 | $WebProxyCredentials = (New-Object Net.NetworkCredential($ProxyUser.Trim(),$ProxyPassword)).GetCredential($ProxyServer.Trim(),$ProxyPort,"KERBEROS") 304 | $WebProxy.Credentials = $WebProxyCredentials 305 | $WebClient.Proxy = $WebProxy 306 | } 307 | elseif($ProxyServer -and $ProxyPort) 308 | { 309 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 310 | Write-Host Downloading DriverPackCatalog File using Custom Proxy Settings. `n 311 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 312 | $WebClient.Proxy = $WebProxy 313 | } 314 | 315 | $WebClient.DownloadFile($DriverCabCatalog, "$DriverCabCatalogFile") 316 | 317 | if (Test-Path "$DriverCabCatalogFile") 318 | { 319 | Write-Host DriverPackCatalog file downloaded successful. `n 320 | Add-Content -Path $LogFilePath -Value "DriverPackCatalog file downloaded successful." 321 | } 322 | else 323 | { 324 | Write-Host DriverPackCatalog file is not downloaded! `n -BackgroundColor Red 325 | Add-Content -Path $LogFilePath -Value "DriverPackCatalog file download failed!" 326 | exit(1) 327 | } 328 | } 329 | catch [System.Net.WebException] 330 | { 331 | Write-Error "$($_.Exception)" 332 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 333 | exit(1) 334 | } 335 | 336 | 337 | # *** To Extract the DriverPackCatalog file. *** 338 | 339 | try { 340 | Write-Host Extracting DriverPackCatalog file... `n 341 | Add-Content -Path $LogFilePath -Value "Extracting DriverPackCatalog file..." 342 | expand -r $DriverCabCatalogFile $DriverDownloadFolder 343 | if (Test-Path "$DriverCatalogXMLFile") 344 | { 345 | Write-Host DriverPackCatalog file extraction successful. `n 346 | Add-Content -Path $LogFilePath -Value "DriverPackCatalog file extraction successful." 347 | } 348 | else 349 | { 350 | Write-Host DriverPackCatalog XML file extraction failed! `n -BackgroundColor Red 351 | Add-Content -Path $LogFilePath -Value "DriverPackCatalog XML file extraction failed!" 352 | exit(1) 353 | } 354 | } 355 | catch [Exception] 356 | { 357 | Write-Error "$($_.Exception)" 358 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 359 | exit(1) 360 | } 361 | 362 | try { 363 | [xml]$CatalogXML = Get-Content -Path $DriverCatalogXMLFile -ErrorAction Ignore 364 | [array]$DriverPackages = $CatalogXML.DriverPackManifest.DriverPackage 365 | $urlBase = "https://downloads.dell.com/" 366 | $NoDriverMatchFound = $true 367 | foreach ($DriverPackage in $DriverPackages) 368 | { 369 | # Driver Package Name 370 | $DriverPackageName = $DriverPackage.Name.Display.'#cdata-section'.Trim() 371 | # Driver Match Found Flag 372 | $DriverMatchFound = $false 373 | # Driver Download url 374 | $DriverDownloadPath = -join($urlBase, $DriverPackage.path) 375 | # Driver Download Path 376 | $DriverDownloadDestPath = -join($DriverDownloadFolder,"\$DriverPackageName") 377 | 378 | foreach ($SupportedSystems in $DriverPackage.SupportedSystems.Brand) 379 | { 380 | $SystemIDFromCatalog = $SupportedSystems.Model.systemID 381 | 382 | # Check for System ID Match 383 | if ($SystemIDFromCatalog -eq $SystemID) 384 | { 385 | # Check for System OS Match 386 | foreach ($SupportedOS in $DriverPackage.SupportedOperatingSystems) 387 | { 388 | if ($SupportedOS.OperatingSystem.Display.'#cdata-section'.Trim() -match $SystemOS) 389 | { 390 | $NoDriverMatchFound = $false 391 | $DriverMatchFound = $true 392 | } 393 | } 394 | } 395 | } 396 | 397 | # *** Download the driver if both System ID and System OS match found. *** 398 | 399 | if ($DriverMatchFound) 400 | { 401 | Write-Host Downloading driver file! `n The download might take some time... `n Make sure the internet is not disconnected! `n -BackgroundColor Gray 402 | Add-Content -Path $LogFilePath -Value "Downloading driver file..." 403 | # Adding stopwatch to get the total time taken to download the driver. 404 | $StopWatch = [system.diagnostics.stopwatch]::StartNew() 405 | $WebClient = New-Object -TypeName System.Net.WebClient 406 | 407 | # *** Check if Custom Proxy Settings is passed and set the custom proxy settings. *** 408 | if($ProxyServer -and $ProxyPort -and $ProxyUser -and $ProxyPassword) 409 | { 410 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 411 | Write-Host Downloading Driver using Custom Proxy Settings using Proxy Credentials. `n 412 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 413 | $WebProxyCredentials = (New-Object Net.NetworkCredential($ProxyUser.Trim(),$ProxyPassword)).GetCredential($ProxyServer.Trim(),$ProxyPort,"KERBEROS") 414 | $WebProxy.Credentials = $WebProxyCredentials 415 | $WebClient.Proxy = $WebProxy 416 | } 417 | elseif($ProxyServer -and $ProxyPort) 418 | { 419 | $ProxyServerAddress = $ProxyServer.Trim() + ":" + $ProxyPort.ToString() 420 | Write-Host Downloading Driver using Custom Proxy Settings. `n 421 | $WebProxy = New-Object System.Net.WebProxy($ProxyServerAddress,$true) 422 | $WebClient.Proxy = $WebProxy 423 | } 424 | 425 | $WebClient.DownloadFile($DriverDownloadPath, $DriverDownloadDestPath) 426 | $StopWatch.Stop() 427 | $TotalDriverDownloadTime = $StopWatch.Elapsed 428 | 429 | # *** Once Driver Download is completed Check if the SHA256 hash matches with the downloaded driver. *** 430 | if (Test-Path "$DriverDownloadDestPath") 431 | { 432 | Write-Host "Driver download successful: $DriverPackageName `n" 433 | Add-Content -Path $LogFilePath -Value "Driver download successful: $DriverPackageName" 434 | Write-Host "Total time taken to download driver $DriverPackageName (hh:mm:ss.ms): $TotalDriverDownloadTime `n" 435 | Add-Content -Path $LogFilePath -Value "Total time taken to download driver $DriverPackageName (hh:mm:ss.ms): $TotalDriverDownloadTime" 436 | # MD5 hash from the xml file 437 | $MD5Hash = $DriverPackage.Cryptography.Hash | Where-Object { $_.algorithm -eq 'SHA256' } | Select-Object -ExpandProperty "#text" 438 | # MD5 hash of the downloaded driver file 439 | $DriverFileMD5Hash = Get-FileHash $DriverDownloadDestPath -Algorithm SHA256 440 | if($MD5Hash -eq $DriverFileMD5Hash.Hash) 441 | { 442 | Write-Host "MD5 hash match successful - $DriverPackageName. `n" 443 | Add-Content -Path $LogFilePath -Value "MD5 hash match successful - $DriverPackageName." 444 | # Extract downloaded driver file 445 | Write-Host "Extracting driver file - $DriverPackageName. `n" 446 | Add-Content -Path $LogFilePath -Value "Extracting driver file - $DriverPackageName." 447 | Write-Host "The extraction might take some time... `n Please wait for the extraction to complete... " -BackgroundColor Gray 448 | $DriverPackageLocation = Join-Path -Path $DriverDownloadFolder -ChildPath $DriverPackageName 449 | $DriverPackageExtractFolderName = [System.IO.Path]::GetFileNameWithoutExtension($DriverPackageName) 450 | $DriverPackExtractLocation = Join-Path -Path $DriverDownloadFolder -ChildPath $DriverPackageExtractFolderName 451 | try 452 | { 453 | if($DriverPackageName -match ".exe") 454 | { 455 | Start-Process -FilePath $DriverPackageLocation -ArgumentList "/s /e=$DriverPackExtractLocation" -Wait -NoNewWindow -PassThru 456 | } 457 | else 458 | { 459 | # Create extraction folder for .cab extraction 460 | New-Item -Path $DriverPackExtractLocation -ItemType Directory -Force | Out-Null 461 | # Extract all contents into the extraction folder 462 | expand -r -F:* $DriverPackageLocation $DriverPackExtractLocation | Out-Null 463 | } 464 | } 465 | catch [Exception] 466 | { 467 | Write-Host "Extraction of DriverPack $DriverPackageName failed! `n" 468 | Add-Content -Path $LogFilePath -Value "Extraction of DriverPack $DriverPackageName failed!" 469 | Write-Error "$($_.Exception)" 470 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 471 | exit(1) 472 | } 473 | Write-Host "Driver extraction successful - $DriverPackageName. `n" 474 | Add-Content -Path $LogFilePath -Value "Driver extraction successful - $DriverPackageName." 475 | # Install the Driver using PNPUTIL command 476 | $DriverFilestoInstall = Join-Path -Path $DriverPackExtractLocation -ChildPath "*.inf" 477 | Write-Host "Installing driver - $DriverPackageName. `n" 478 | Add-Content -Path $LogFilePath -Value "Installing driver - $DriverPackageName." 479 | Write-Host "The installation might take some time... `n Please wait for the installation to complete... " -BackgroundColor Gray 480 | try 481 | { 482 | PNPUtil.exe /add-driver $DriverFilestoInstall /subdirs /install | Tee-Object -Append -File $LogFilePath 483 | } 484 | catch [Exception] 485 | { 486 | Write-Host "$DriverPackageName Installation failed! `n" 487 | Add-Content -Path $LogFilePath -Value "$DriverPackageName Installation failed!" 488 | Write-Error "$($_.Exception)" 489 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 490 | exit(1) 491 | } 492 | Write-Host "$DriverPackageName Installation Completed. `n" 493 | Add-Content -Path $LogFilePath -Value "$DriverPackageName Installation Completed." 494 | $DriverInstallSuccess = $true 495 | } 496 | else 497 | { 498 | Write-Host "MD5 has match failed. Hence, deleting the driver file $DriverPackageName. `n" 499 | Add-Content -Path $LogFilePath -Value "MD5 has match failed. Hence, deleting the driver file $DriverPackageName." 500 | Write-Host "Driver installation was not successful! `n" 501 | Add-Content -Path $LogFilePath -Value "Driver installation was not successful!" 502 | Remove-Item -Path $DriverDownloadDestPath -Recurse -Force | Out-Null 503 | } 504 | } 505 | else 506 | { 507 | Write-Host "Driver download failed: $DriverPackageName `n" 508 | Add-Content -Path $LogFilePath -Value "Driver download failed: $DriverPackageName" 509 | } 510 | 511 | } 512 | 513 | } 514 | 515 | if($NoDriverMatchFound -eq $true) 516 | { 517 | Write-Host "No Driver Match found for the SystemID: $SystemID, OS: $SystemOS. `n" 518 | Write-Host "Contact Dell Support. `n" 519 | Add-Content -Path $LogFilePath -Value "No Driver Match found for the SystemID: $SystemID, OS: $SystemOS." 520 | Add-Content -Path $LogFilePath -Value "Contact Dell Support." 521 | } 522 | 523 | } 524 | catch [Exception] 525 | { 526 | Write-Error "$($_.Exception)" 527 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 528 | } 529 | 530 | } 531 | catch [Exception] 532 | { 533 | Write-Error "$($_.Exception)" 534 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 535 | } 536 | Finally 537 | { 538 | # Delete all contents from DownloadFolder except Log file 539 | if($LogFilePath) 540 | { 541 | if($DriverDownloadFolder) 542 | { 543 | try 544 | { 545 | Get-ChildItem -Path $DriverDownloadFolder -Recurse -exclude $LogFileName | 546 | Select -ExpandProperty FullName | 547 | Where {$_ -notlike $LogFilePath} | 548 | sort length -Descending | 549 | Remove-Item -Recurse -Force | Out-Null 550 | } 551 | catch [Exception] 552 | { 553 | Write-Host "Deleting files from $DriverDownloadFolder failed! Manual clean-up is required!" 554 | Write-Error "$($_.Exception)" 555 | Add-Content -Path $LogFilePath -Value "Deleting files from $DriverDownloadFolder failed! Manual clean-up is required!" 556 | Add-Content -Path $LogFilePath -Value "$($_.Exception)" 557 | } 558 | } 559 | Write-Host "Function Install-DellDriverFiles Executed" 560 | $FinishTime = Get-Date 561 | Add-Content -Path $LogFilePath -Value "------------------------------------" 562 | 563 | Add-Content -Path $LogFilePath -Value "Function Install-DellDriverFiles Executed" 564 | 565 | Add-Content -Path $LogFilePath -Value " $FinishTime " 566 | 567 | Add-Content -Path $LogFilePath -Value "------------------------------------" 568 | #restart the system if required, using Powershell Script 569 | if($Restart -and $DriverInstallSuccess) 570 | { 571 | Write-Host "Restarting System... `n" 572 | Add-Content -Path $LogFilePath -Value "Restarting System..." 573 | #CAUTION: USER MIGHT LOSE UNSAVED WORK 574 | Restart-DellComputer -Seconds 10 575 | } 576 | } 577 | } 578 | } 579 | 580 | --------------------------------------------------------------------------------