简体   繁体   中英

PowerShell Scheduled Task creation error on server 2012 R2

The below code works if I run it manually on server 2012 R2 but when I run it in my companies pipeline, I get an error I don't understand. The rest of the script runs just fine.

This code also works just fine in my pipeline for server 2016 and server 2019. So there is something with server 2012 R2 that is different and I can't determine what it is.

Code segment that fails:

# Get path where command is being run from
$here = Split-Path $script:MyInvocation.MyCommand.Path

$driversPath = (Join-Path $here 'drivers')
$PS1File = (Join-Path $driversPath 'Install-ChipsetDrivers.ps1')
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File $PS1File -EXEFilesPath $driversPath"
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName 'Install Chipset Drivers' -Action $action -Trigger $trigger -Principal $principal -Description 'Installs any Chipset drivers that are missing' -ErrorAction Stop -Force

Error:

Register-ScheduledTask: Cannot process argument transformation on parameter 'Trigger'. Cannot convert
value \"Microsoft.PowerShell.ScheduledJob.ScheduledJobTrigger\" to type
\"Microsoft.Management.Infrastructure.CimInstance[]\". Error: \"Cannot convert the
\"Microsoft.PowerShell.ScheduledJob.ScheduledJobTrigger\" value of type
\"Deserialized.Microsoft.PowerShell.ScheduledJob.ScheduledJobTrigger\" to type
\"Microsoft.Management.Infrastructure.CimInstance\".

Entire Script:

# Controller script to run all profiles in package

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version 1.0
$LASTEXITCODE = 0 # Required for exit code captures after running the pnputil.exe command

# Get path where command is being run from
$here = Split-Path $script:MyInvocation.MyCommand.Path

$OSInfo = Get-CimInstance Win32_OperatingSystem

# fix path for pnputil.exe
$MyPath = ";C:\WINDOWS\system32"
$env:path += $MyPath

Write-Verbose "Adding to PSModulePath" -Verbose
$module_path = Join-Path $here modules
$env:PSModulePath += ";$module_path"

$fail = $false

Write-Verbose "Begin Driver Installation" -Verbose

# Determine which OS this test is being run against
switch (Get-CimInstance win32_operatingsystem | Select-Object -exp Caption) {
  { $_ -match '2019' } {
    $OSversion = '2019'
  }
  { $_ -match '2016' } {
    $OSversion = '2016'
  }
  default {
    $OSversion = '2012 R2'
  }
}

# Expected text when a driver is found to be incompatible with the given OS
$incompatible_text = 'Adding the driver package failed : The software was tested for compliance with Windows Logo requirements on a different version of Windows, and may not be compatible with this version.'

# Should any drivers attempt to be installed that are incompatible, they will be listed in incompatible_drivers.json
$incompatible_drivers_file = (Join-Path $env:windir 'setup\incompatible_drivers.json')

# $os_specific_drivers_path = (Join-Path $env:windir 'setup\01-os_specific_drivers.json')
# $install_drivers_path = (Join-Path $env:windir 'setup\02-install_drivers.json')
# $drivers_during_install_path = (Join-Path $env:windir 'setup\03-install_drivers.json')
$driver_count_path = (Join-Path $env:windir 'setup\installed_drivers_count.json')
$driver_count = @{count = 0 }
$incompatible = @{exclusions = @() }

# Drivers that have been manually selected to be excluded from being installed
$exclude_drivers = Get-Content (Join-Path $here exclude_drivers.json) -Raw | ConvertFrom-Json | Select-Object -exp Exclusions

# Gets the drivers from the driverDetails.json file for all drivers that should be installed for the given OS
$os_specific_drivers = Get-Content (Join-Path $here 'drivers' driverDetails.json) -Raw | ConvertFrom-Json | Where-Object OS -Match $OSversion

Write-Verbose "Getting list of drivers to exclude from $here\exclude_drivers.json" -Verbose
$install_drivers = $os_specific_drivers | ForEach-Object {
  $cpPathDir = (Join-Path $here 'drivers' $($_.cpFile))
  $InfFiles = Get-ChildItem $cpPathDir -Filter *.inf | Where-Object name -NotIn $exclude_drivers
  $InfFiles
} | Sort-Object FullName

# $os_specific_drivers | Out-File -FilePath $os_specific_drivers_path
# $install_drivers | Out-File -FilePath $install_drivers_path

# This is required for validating all drivers were installed during pester testing
$driver_count.count = ($install_drivers | Measure-Object).count

Write-Verbose "Installing $($driver_count.count) drivers" -Verbose

foreach ($inf in $install_drivers) {
  Write-Verbose "Installing driver $($inf.FullName)" -Verbose
  # Determine if the OS is version 2012 R2 or prior.  This is required due to syntax changes in pnputil staring in 2016
  if ([version]$OSInfo.Version -le [version]'6.3.9600') {
    $output = pnputil.exe -a "`"$($inf.FullName)`""
  }
  else {
    $output = pnputil.exe /add-driver "$($inf.FullName)"
  }

  # If there was an error during the driver install, was it due to the driver not being compatible with the given OS or due to an unknown error
  if ($LASTEXITCODE -ne 0) {
    if ($output | Select-String $incompatible_text) {
      Write-Verbose "$($inf.FullName) install exited with non-zero exit code.  Driver is NOT compatible with this version of windows, adding to skipped install list." -Verbose
      $incompatible.exclusions += $inf.Name
    }
    else {
      Write-Verbose "$($inf.FullName) install exited with non-zero exit code." -Verbose
      $fail = $true
    }
  }
  $output
}

if ($incompatible.exclusions) {
  # Write incompatible drivers to a file so they will be skipped during testing
  $incompatible | ConvertTo-Json -Depth 5 | Out-File $incompatible_drivers_file -Force
  Write-Verbose $($incompatible | ConvertTo-Json -Depth 5) -Verbose
}

# Save number of installed drivers to disk for tests
$driver_count | ConvertTo-Json -Depth 2 | Out-File $driver_count_path

# Registers a Scheduled Task that will attempt to install drivers (mostly chipset drivers) that cannon be installed via their INF files at image creation.  This scheduled task will be removed once run.
$driversPath = (Join-Path $here 'drivers')
$PS1File = (Join-Path $driversPath 'Install-ChipsetDrivers.ps1')
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File $PS1File -EXEFilesPath $driversPath"
$scheduledTrigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName 'Install Chipset Drivers' -Action $action -Trigger $scheduledTrigger -Principal $principal -Description 'Installs any Chipset drivers that are missing' -ErrorAction Stop -Force

Write-Verbose "End Driver Install" -Verbose

if ($fail) { exit 1 }

I ended up using the old CMD command to generate the scheduled task and it appears to work around the PowerShell issue.

$driversPath = (Join-Path $here 'drivers')
$PS1File = (Join-Path $driversPath 'Install-ChipsetDrivers.ps1')
$taskName = "Install Chipset Drivers"
$user = "NT AUTHORITY\SYSTEM"
$privileges = "HIGHEST"
$action = "PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File $PS1File -EXEFilesPath $driversPath"

SCHTASKS /CREATE /SC ONSTART /RU $user /RL $privileges /TN $taskName /TR $action

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM