Public/OSDCloudTS/Install-DellApps.ps1

Function Install-DellApps {
    <#
    Gary Blok | @gwblok
 
    Updates on DELL machines by finding latest version avialble in Dell Command Update XML, Downloading and installing, then triggers a Reboot
 
    Used the Dell DCU Legacy Install, not the Universal / UWP app Install. If you want to modify it for yourself, search for "UWP" and make needed changes.
 
    Changes:
    23.03.09
     - Updated to deal with multiple DCU's being returned
     - Added App Matching, if you already have "Universal" installed, it will install the Universal.
     - Removed Date Time modification on whim that it is causing issues
     - Updated some variable names from DCU... to DCM ... to make reading code easier.
    23.11.09
     - Updated to fix issue https://github.com/gwblok/garytown/issues/12
       - When DCU or DCM is NOT installed, set version to 0.0.0.0 instead of NULL
 
    #>


    $temproot = "$env:windir\temp"
    $ScriptVersion = "24.05.21.1"
    $whoami = $env:USERNAME
    $OSDCloudFolder = "C:\OSDCloud"
    $LogFilePath = "$OSDCloudFolder\Logs"
    $LogFile = "$LogFilePath\Dell-Updates.log"
    $scriptName = "Dell DCU Update - From Cloud"
    $SystemSKUNumber = (Get-CimInstance -ClassName Win32_ComputerSystem).SystemSKUNumber
    #$SystemSKUNumber = "0B0B" #Testing
    $Manufacturer = (Get-CimInstance -ClassName Win32_ComputerSystem).Manufacturer
    $CabPathIndex = "$temproot\DellCabDownloads\CatalogIndexPC.cab"
    $CabPathIndexModel = "$temproot\DellCabDownloads\CatalogIndexModel.cab"
    $DellCabExtractPath = "$temproot\DellCabDownloads\DellCabExtract"
    $Compliance = $true
    $Remediate = $true
    if ($Remediate -eq $true){$ComponentText = "DCU Apps - Remediation"}
    else {$ComponentText = "DCU Apps - Detection"}


    if (!(Test-Path -Path $LogFilePath)){New-Item -Path $LogFilePath -ItemType Directory -Force | Out-Null}                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    Function Get-InstalledApplication {
      [CmdletBinding()]
      Param(
        [Parameter(
          Position=0,
          ValueFromPipeline=$true,
          ValueFromPipelineByPropertyName=$true
        )]
        [String[]]$ComputerName=$ENV:COMPUTERNAME,

        [Parameter(Position=1)]
        [String[]]$Properties,

        [Parameter(Position=2)]
        [String]$IdentifyingNumber,

        [Parameter(Position=3)]
        [String]$Name,

        [Parameter(Position=4)]
        [String]$Publisher
      )
      Begin{
        Function IsCpuX86 ([Microsoft.Win32.RegistryKey]$hklmHive){
          $regPath='SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
          $key=$hklmHive.OpenSubKey($regPath)

          $cpuArch=$key.GetValue('PROCESSOR_ARCHITECTURE')

          if($cpuArch -eq 'x86'){
            return $true
          }else{
            return $false
          }
        }
      }
      Process{
        foreach($computer in $computerName){
          $regPath = @(
            'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
            'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
          )

          Try{
            $hive=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(
              [Microsoft.Win32.RegistryHive]::LocalMachine, 
              $computer
            )
            if(!$hive){
              continue
            }
        
            # if CPU is x86 do not query for Wow6432Node
            if($IsCpuX86){
              $regPath=$regPath[0]
            }

            foreach($path in $regPath){
              $key=$hive.OpenSubKey($path)
              if(!$key){
                continue
              }
              foreach($subKey in $key.GetSubKeyNames()){
                $subKeyObj=$null
                if($PSBoundParameters.ContainsKey('IdentifyingNumber')){
                  if($subKey -ne $IdentifyingNumber -and 
                    $subkey.TrimStart('{').TrimEnd('}') -ne $IdentifyingNumber){
                    continue
                  }
                }
                $subKeyObj=$key.OpenSubKey($subKey)
                if(!$subKeyObj){
                  continue
                }
                $outHash=New-Object -TypeName Collections.Hashtable
                $appName=[String]::Empty
                $appName=($subKeyObj.GetValue('DisplayName'))
                if($PSBoundParameters.ContainsKey('Name')){
                  if($appName -notlike $name){
                    continue
                  }
                }
                if($appName){
                  if($PSBoundParameters.ContainsKey('Properties')){
                    if($Properties -eq '*'){
                      foreach($keyName in ($hive.OpenSubKey("$path\$subKey")).GetValueNames()){
                        Try{
                          $value=$subKeyObj.GetValue($keyName)
                          if($value){
                            $outHash.$keyName=$value
                          }
                        }Catch{
                          Write-Warning "Subkey: [$subkey]: $($_.Exception.Message)"
                          continue
                        }
                      }
                    }else{
                      foreach ($prop in $Properties){
                        $outHash.$prop=($hive.OpenSubKey("$path\$subKey")).GetValue($prop)
                      }
                    }
                  }
                  $outHash.Name=$appName
                  $outHash.IdentifyingNumber=$subKey
                  $outHash.Publisher=$subKeyObj.GetValue('Publisher')
                  if($PSBoundParameters.ContainsKey('Publisher')){
                    if($outHash.Publisher -notlike $Publisher){
                      continue
                    }
                  }
                  $outHash.ComputerName=$computer
                  $outHash.Version=$subKeyObj.GetValue('DisplayVersion')
                  $outHash.Path=$subKeyObj.ToString()
                  New-Object -TypeName PSObject -Property $outHash
                }
              }
            }
          }Catch{
            Write-Error $_
          }
        }
      }
      End{}
    }
    function CMTraceLog {
        [CmdletBinding()]
        Param (
            [Parameter(Mandatory=$false)]
            $Message,
 
            [Parameter(Mandatory=$false)]
            $ErrorMessage,
 
            [Parameter(Mandatory=$false)]
            $Component = $ComponentText,
 
            [Parameter(Mandatory=$false)]
            [int]$Type,
        
            [Parameter(Mandatory=$true)]
            $LogFile = "$env:ProgramData\Intune\Logs\IForgotToNameTheLogVar.log"
            )
        <#
        Type: 1 = Normal, 2 = Warning (yellow), 3 = Error (red)
        #>

        $Time = Get-Date -Format "HH:mm:ss.ffffff"
        $Date = Get-Date -Format "MM-dd-yyyy"
 
        if ($ErrorMessage -ne $null) {$Type = 3}
        if ($Component -eq $null) {$Component = " "}
        if ($Type -eq $null) {$Type = 1}
 
        $LogMessage = "<![LOG[$Message $ErrorMessage" + "]LOG]!><time=`"$Time`" date=`"$Date`" component=`"$Component`" context=`"`" type=`"$Type`" thread=`"`" file=`"`">"
        $LogMessage | Out-File -Append -Encoding UTF8 -FilePath $LogFile
    }

    CMTraceLog -Message  "---------------------------------" -Type 1 -LogFile $LogFile
    CMTraceLog -Message  "Starting $ScriptName, $ScriptVersion | Remediation Mode $Remediate" -Type 1 -LogFile $LogFile
    CMTraceLog -Message  "Running as $whoami" -Type 1 -LogFile $LogFile

    if ($Manufacturer -match "Dell"){

        $InstallApps = Get-InstalledApplication
        $InstalledDCM = $InstallApps | Where-Object {$_.Name -eq 'Dell Command | Monitor'}
        $InstalledDCU = $InstallApps | Where-Object {$_.Name -match 'Dell Command' -and $_.Name -match 'Update'}

        If ($InstalledDCM){[Version]$DCM_InstalledVersion = $InstalledDCM.Version}
        If ($InstalledDCU){[Version]$DCU_InstalledVersion = $InstalledDCU.Version}


        # Pull down Dell XML CAB used in Dell Command Update ,extract and Load
        if (!(Test-Path $DellCabExtractPath)){$newfolder = New-Item -Path $DellCabExtractPath -ItemType Directory -Force}
        Write-Host "Downloading Dell Cab" -ForegroundColor Yellow
        Invoke-WebRequest -Uri "https://downloads.dell.com/catalog/CatalogIndexPC.cab" -OutFile $CabPathIndex -UseBasicParsing -Verbose
        [int32]$n=1
        While(!(Test-Path $CabPathIndex) -and $n -lt '3'){
            Invoke-WebRequest -Uri "https://downloads.dell.com/catalog/CatalogIndexPC.cab" -OutFile $CabPathIndex -UseBasicParsing -Verbose
            $n++
        }
        If(Test-Path "$DellCabExtractPath\DellSDPCatalogPC.xml"){Remove-Item -Path "$DellCabExtractPath\DellSDPCatalogPC.xml" -Force}
        Start-Sleep -Seconds 1
        if (test-path $DellCabExtractPath){Remove-Item -Path $DellCabExtractPath -Force -Recurse}
        New-Item -Path $DellCabExtractPath -ItemType Directory | Out-Null
        Write-Host "Expanding the Cab File..." -ForegroundColor Yellow
        $Expand = expand $CabPathIndex $DellCabExtractPath\CatalogIndexPC.xml

        write-host "Loading Dell Catalog XML.." -ForegroundColor Yellow
        [xml]$XMLIndex = Get-Content "$DellCabExtractPath\CatalogIndexPC.xml" -Verbose


        #Dig Through Dell XML to find Model of THIS Computer (Based on System SKU)
        $XMLModel = $XMLIndex.ManifestIndex.GroupManifest | Where-Object {$_.SupportedSystems.Brand.Model.systemID -match $SystemSKUNumber}
        if ($XMLModel){
            CMTraceLog -Message  "Found Match for SKU: $SystemSKUNumber" -Type 1 -LogFile $LogFile
            CMTraceLog -Message  "Downloaded Dell DCU XML, now looking for Model Updates" -Type 1 -LogFile $LogFile
            Invoke-WebRequest -Uri "http://downloads.dell.com/$($XMLModel.ManifestInformation.path)" -OutFile $CabPathIndexModel -UseBasicParsing -Verbose
            if (Test-Path $CabPathIndexModel){
                $Expand = expand $CabPathIndexModel $DellCabExtractPath\CatalogIndexPCModel.xml
                [xml]$XMLIndexCAB = Get-Content "$DellCabExtractPath\CatalogIndexPCModel.xml" -Verbose
                $DCUAvailable = $XMLIndexCAB.Manifest.SoftwareComponent | Where-Object {$_.ComponentType.value -eq ""}
                $DCUAppsAvailable = $XMLIndexCAB.Manifest.SoftwareComponent | Where-Object {$_.ComponentType.value -eq "APAC"}
                $AppNames = $DCUAppsAvailable.name.display.'#cdata-section' | Select-Object -Unique
                #If you already have the Universal Version Installed:
                if ($InstalledDCU -match "Universal"){
                    $AppDCUVersion = ([Version[]]$Version = ($DCUAppsAvailable | Where-Object {$_.path -match 'command-update' -and $_.SupportedOperatingSystems.OperatingSystem.osArch -match "x64" -and $_.path -match 'universal'}).vendorVersion) | Sort-Object | Select-Object -Last 1
                    $AppDCU = $DCUAppsAvailable | Where-Object {$_.path -match 'command-update' -and $_.SupportedOperatingSystems.OperatingSystem.osArch -match "x64" -and $_.path -match 'universal' -and $_.vendorVersion -eq $AppDCUVersion}
                    if ($AppDCU.Count -gt 1){
                        $AppDCU = $AppDCU | Select-Object -First 1
                    }
                }
                #This is using the x86 Windows version, not the UWP app
                else {
                    $AppDCUVersion = ([Version[]]$Version = ($DCUAppsAvailable | Where-Object {$_.path -match 'command-update' -and $_.SupportedOperatingSystems.OperatingSystem.osArch -match "x64" -and $_.Description.Display.'#cdata-section' -notmatch "UWP" -and $_.path -notmatch 'universal'}).vendorVersion) | Sort-Object | Select-Object -Last 1
                    $AppDCU = $DCUAppsAvailable | Where-Object {$_.path -match 'command-update' -and $_.SupportedOperatingSystems.OperatingSystem.osArch -match "x64" -and $_.Description.Display.'#cdata-section' -notmatch "UWP" -and $_.path -notmatch 'universal' -and $_.vendorVersion -eq $AppDCUVersion}
                    if ($AppDCU.Count -gt 1){
                        $AppDCU = $AppDCU | Select-Object -First 1
                    }
                }
                $AppDCMVersion = ([Version[]]$Version = ($DCUAppsAvailable | Where-Object {$_.path -match 'Command-Monitor' -and $_.SupportedOperatingSystems.OperatingSystem.osArch -match "x64"} | Select-Object -Property vendorVersion).vendorVersion) | Sort-Object | Select-Object -last 1
                $AppDCM = $DCUAppsAvailable | Where-Object {$_.path -match 'Command-Monitor' -and $_.SupportedOperatingSystems.OperatingSystem.osArch -match "x64" -and $_.vendorVersion -eq $AppDCMVersion }
            
                #$DCUDRIVERSAvailable = $XMLIndexCAB.Manifest.SoftwareComponent | Where-Object {$_.ComponentType.value -eq "DRVR"}
                #$DCUFIRMWAREAvailable = $XMLIndexCAB.Manifest.SoftwareComponent | Where-Object {$_.ComponentType.value -eq "FRMW"}

                #Lets CHeck DCU First
                $DellItem = $AppDCU
                If ($InstalledDCU){[Version]$CurrentVersion = $InstalledDCU.Version}
                Else {[Version]$CurrentVersion = 0.0.0.0}
                [Version]$DCUVersion = $DellItem.vendorVersion
                #$DCUReleaseDate = $(Get-Date $DellItem.releaseDate -Format 'yyyy-MM-dd')
                $DCUReleaseDate = $($DellItem.releaseDate)              
                $TargetLink = "http://downloads.dell.com/$($DellItem.path)"
                $TargetFileName = ($DellItem.path).Split("/") | Select-Object -Last 1
                if ($DCUVersion -gt $CurrentVersion){
                    if ($CurrentVersion -eq 0.0.0.0){[String]$CurrentVersion = "Not Installed"}
                    if ($Remediate -eq $true){
                        CMTraceLog -Message  "New Update available: Installed = $CurrentVersion DCU = $DCUVersion" -Type 1 -LogFile $LogFile
                        Write-Host " New Update available: Installed = $CurrentVersion DCU = $DCUVersion" -ForegroundColor Yellow 
                        CMTraceLog -Message  " Title: $($DellItem.Name.Display.'#cdata-section')" -Type 1 -LogFile $LogFile
                        Write-Output " Title: $($DellItem.Name.Display.'#cdata-section')"
                        CMTraceLog -Message  " ----------------------------" -Type 1 -LogFile $LogFile
                        Write-Host " ----------------------------" -ForegroundColor Cyan
                        CMTraceLog -Message  " Severity: $($DellItem.Criticality.Display.'#cdata-section')" -Type 1 -LogFile $LogFile
                        Write-Output " Severity: $($DellItem.Criticality.Display.'#cdata-section')"
                        CMTraceLog -Message  " FileName: $TargetFileName" -Type 1 -LogFile $LogFile
                        Write-Output " FileName: $TargetFileName"
                        CMTraceLog -Message  " Release Date: $DCUReleaseDate" -Type 1 -LogFile $LogFile
                        Write-Output " Release Date: $DCUReleaseDate"
                        CMTraceLog -Message  " KB: $($DellItem.releaseID)" -Type 1 -LogFile $LogFile
                        Write-Output " KB: $($DellItem.releaseID)"
                        CMTraceLog -Message  " Link: $TargetLink" -Type 1 -LogFile $LogFile
                        Write-Output " Link: $TargetLink"
                        CMTraceLog -Message  " Info: $($DellItem.ImportantInfo.URL)" -Type 1 -LogFile $LogFile
                        Write-Output " Info: $($DellItem.ImportantInfo.URL)"
                        CMTraceLog -Message  " Version: $DCUVersion " -Type 1 -LogFile $LogFile
                        Write-Output " Version: $DCUVersion "

                        #Build Required Info to Download and Update CM Package
                        $TargetFilePathName = "$($DellCabExtractPath)\$($TargetFileName)"
                        CMTraceLog -Message  " Running Command: Invoke-WebRequest -Uri $TargetLink -OutFile $TargetFilePathName -UseBasicParsing -Verbose" -Type 1 -LogFile $LogFile
                        Invoke-WebRequest -Uri $TargetLink -OutFile $TargetFilePathName -UseBasicParsing -Verbose

                        #Confirm Download
                        if (Test-Path $TargetFilePathName){
                            CMTraceLog -Message  " Download Complete " -Type 1 -LogFile $LogFile
                            $LogFileName = $TargetFilePathName.replace(".exe",".log")
                            $Arguments = "/s /l=$LogFileName"
                            Write-Output "Starting Update"
                            write-output "Log file = $LogFileName"
                            CMTraceLog -Message  " Running Command: Start-Process $TargetFilePathName $Arguments -Wait -PassThru " -Type 1 -LogFile $LogFile
                            $Process = Start-Process "$TargetFilePathName" $Arguments -Wait -PassThru
                            CMTraceLog -Message  " Update Complete with Exitcode: $($Process.ExitCode)" -Type 1 -LogFile $LogFile
                            write-output "Update Complete with Exitcode: $($Process.ExitCode)"
                            If($Process -ne $null -and $Process.ExitCode -eq '2'){
                                $RestartComputer = $true
                            }
                        }
                        else{
                            CMTraceLog -Message  " FAILED TO DOWNLOAD Update" -Type 3 -LogFile $LogFile
                            Write-Host " FAILED TO DOWNLOAD Update" -ForegroundColor Red
                            $Compliance = $false
                        }
                    }
                    else{
                        #Needs Remediation
                        CMTraceLog -Message  "New Update available for $($DellItem.Name.Display.'#cdata-section'): Installed = $CurrentVersion | DCU = $DCUVersion | Remediation Required" -Type 1 -LogFile $LogFile
                        $Compliance = $false
                    }
            
                }
                else{
                    #Compliant
                    Write-Host " Update in DCU XML for $($DellItem.Name.Display.'#cdata-section') same as Installed Version: $CurrentVersion" -ForegroundColor Yellow
                    CMTraceLog -Message  " Update in DCU XML for $($DellItem.Name.Display.'#cdata-section') same as Installed Version: $CurrentVersion" -Type 1 -LogFile $LogFile
                }

                #Lets CHeck DCM Now
                $DellItem = $AppDCM
                If ($InstalledDCM){[Version]$CurrentVersion = $InstalledDCM.Version}
                Else {[Version]$CurrentVersion = 0.0.0.0}


                [Version]$DCMVersion = $DellItem.vendorVersion
                #$DCMReleaseDate = $(Get-Date $DellItem.releaseDate -Format 'yyyy-MM-dd')
                $DCMReleaseDate = $($DellItem.releaseDate)            
                $TargetLink = "http://downloads.dell.com/$($DellItem.path)"
                $TargetFileName = ($DellItem.path).Split("/") | Select-Object -Last 1

                if ($DCMVersion -gt $CurrentVersion){
                    if ($CurrentVersion -eq 0.0.0.0){[String]$CurrentVersion = "Not Installed"}
                    if ($Remediate -eq $true){
                        CMTraceLog -Message  "New Update available: Installed = $CurrentVersion DCM = $DCMVersion" -Type 1 -LogFile $LogFile
                        Write-Host " New Update available: Installed = $CurrentVersion DCM = $DCMVersion" -ForegroundColor Yellow 
                        CMTraceLog -Message  " Title: $($DellItem.Name.Display.'#cdata-section')" -Type 1 -LogFile $LogFile
                        Write-Output " Title: $($DellItem.Name.Display.'#cdata-section')"
                        CMTraceLog -Message  " ----------------------------" -Type 1 -LogFile $LogFile
                        Write-Host " ----------------------------" -ForegroundColor Cyan
                        CMTraceLog -Message  " Severity: $($DellItem.Criticality.Display.'#cdata-section')" -Type 1 -LogFile $LogFile
                        Write-Output " Severity: $($DellItem.Criticality.Display.'#cdata-section')"
                        CMTraceLog -Message  " FileName: $TargetFileName" -Type 1 -LogFile $LogFile
                        Write-Output " FileName: $TargetFileName"
                        CMTraceLog -Message  " Release Date: $DCMReleaseDate" -Type 1 -LogFile $LogFile
                        Write-Output " Release Date: $DCMReleaseDate"
                        CMTraceLog -Message  " KB: $($DellItem.releaseID)" -Type 1 -LogFile $LogFile
                        Write-Output " KB: $($DellItem.releaseID)"
                        CMTraceLog -Message  " Link: $TargetLink" -Type 1 -LogFile $LogFile
                        Write-Output " Link: $TargetLink"
                        CMTraceLog -Message  " Info: $($DellItem.ImportantInfo.URL)" -Type 1 -LogFile $LogFile
                        Write-Output " Info: $($DellItem.ImportantInfo.URL)"
                        CMTraceLog -Message  " Version: $DCUVersion " -Type 1 -LogFile $LogFile
                        Write-Output " Version: $DCMVersion "

                        #Build Required Info to Download and Update CM Package
                        $TargetFilePathName = "$($DellCabExtractPath)\$($TargetFileName)"
                        CMTraceLog -Message  " Running Command: Invoke-WebRequest -Uri $TargetLink -OutFile $TargetFilePathName -UseBasicParsing -Verbose " -Type 1 -LogFile $LogFile
                        Invoke-WebRequest -Uri $TargetLink -OutFile $TargetFilePathName -UseBasicParsing -Verbose

                        #Confirm Download
                        if (Test-Path $TargetFilePathName){
                            CMTraceLog -Message  " Download Complete " -Type 1 -LogFile $LogFile
                                     
                            $LogFileName = $TargetFilePathName.replace(".exe",".log")
                            $Arguments = "/s /l=$LogFileName"
                            Write-Output "Starting Update"
                            write-output "Log file = $LogFileName"
                            CMTraceLog -Message  " Running Command: Start-Process $TargetFilePathName $Arguments -Wait -PassThru " -Type 1 -LogFile $LogFile
                            $Process = Start-Process "$TargetFilePathName" $Arguments -Wait -PassThru
                            CMTraceLog -Message  " Update Complete with Exitcode: $($Process.ExitCode)" -Type 1 -LogFile $LogFile
                            write-output "Update Complete with Exitcode: $($Process.ExitCode)"
                    
                            If($Process -ne $null -and $Process.ExitCode -eq '2'){
                                $RestartComputer = $true
                            }
                        }
                        else{
                            CMTraceLog -Message  " FAILED TO DOWNLOAD Update" -Type 3 -LogFile $LogFile
                            Write-Host " FAILED TO DOWNLOAD Update" -ForegroundColor Red
                            $Compliance = $false
                        }
                    }
                    else{
                        #Needs Remediation
                        #$DellItem.Name.Display.'#cdata-section'
                        CMTraceLog -Message  "New Update available for $($DellItem.Name.Display.'#cdata-section'): Installed = $CurrentVersion | DCU = $DCUVersion | Remediation Required" -Type 1 -LogFile $LogFile
                        $Compliance = $false
                    }
            
                }
                else{
                    #Compliant
                    Write-Host " Update in DCU XML for $($DellItem.Name.Display.'#cdata-section') same as Installed Version: $CurrentVersion" -ForegroundColor Yellow
                    CMTraceLog -Message  " Update in DCU XML for $($DellItem.Name.Display.'#cdata-section') same as Installed Version: $CurrentVersion" -Type 1 -LogFile $LogFile
                }
            }
            else{
                #No Cab with XML was able to download
                Write-Host "No Model Cab Downloaded"
                CMTraceLog -Message  "No Model Cab Downloaded" -Type 2 -LogFile $LogFile
            }
        }
        else{
            #No Match in the DCU XML for this Model (SKUNumber)
            Write-Host "No Match in XML for $SystemSKUNumber"
            CMTraceLog -Message  "No Match in XML for $SystemSKUNumber" -Type 2 -LogFile $LogFile
        }

        if ($Compliance -eq $false){
            CMTraceLog -Message  "Exit Script Non-Compliant" -Type 2 -LogFile $LogFile
            Write-Output "Non-Compliant, Exit 1, to trigger Remediation to Update Software"
            exit 1
        }
        if ($RestartComputer -eq $true) {Write-Host "You should Reboot!!"}
    }
    else{
        CMTraceLog -Message  "This isn't a Dell... exiting... check with admin on why this is running. Script should only be applied to a dynamic group that contains Dell computers." -Type 2 -LogFile $LogFile
    }
}