none
PowerShell scripts How to Install missing drivers from individual setups and avoiding multiple reboots

    Question

  • I am very new to powershell scripts but would like to use it to complete the installation of different hardware drivers on windows xp sp3 machines post imaging. My problem is I don't know the following

    How do I execute the individual setups/msi files on the imaged machine to install the different hardward devices that are missing?
    How do I stop the machine from rebooting until i am happy its necessary?
    How do i control the execution flow to stop different installers & windows hardware setup itself from disrupting the process?

    Tuesday, March 16, 2010 10:43 AM

Answers

  • First I would recommend providing as much drivers as possible within your base image. Install afterwards per client can take a lot of time.
    Second you should verify what kind of isntallers you have. The windows "standard" is MSI. You can install MSI packages with MSIexec.exe using the commandline. Parameters will be used to supress reboots and GUI messages (called silent install) and to remove any needed user-interaction (unattended install). For non MSI installers, you should check the documentation of these packages to obtain info on how to install silent AND unattended. This sourceforge link has proven very valuable to me to get this info.

    In a powershellscript you can then call these programs with the invoke cmdlet or by just placing them one after the other. But in both cases all commands will be executed without waiting.
    You can avoid this in many ways, but I would in fact recommend not to use powershellscripts, but batch files or vbs scripts for this :)
    in batch you use start /wait *command*

    MCSA/MCTS/MCP
    Tuesday, March 16, 2010 11:41 AM
  • Actually what operating system are you dealing with?

    If it's Windows Vista or something newer I think you CAN run the DRVINST command.

    DRVINST C:\DRIVERFOLDER\DRIVERNAME.INF

    Offline .WIM files can have drivers injected to them using DISM.EXE

    DISM.EXE /Mount-wim /WIMFILE:C:\FOLDER\FILENAME.WIM /index:1 /Mountdir:C:\OfflineFoldername\Mounted

    All Drivers in a folder called C:\DRIVERFOLDERNAME (including Subfolders)
    DISM.EXE /IMAGE:C:\OfflineFoldername\Mounted /Add-Driver /driver:C:\DRIVERFOLDERNAME -Recurse

    the Drivers within a Folder called C:\DRIVERFOLDERNAME
    DISM.EXE /IMAGE:C:\OfflineFoldername\Mounted /Add-Driver /driver:C:\DRIVERFOLDERNAME

    A single Driver within a folder called C:\DRIVERFOLDERNAME called Somedriver.inf
    DISM.EXE /IMAGE:C:\OfflineFoldername\Mounted /Add-Driver /driver:C:\DRIVERFOLDERNAME\Somedriver.inf

    When done with the offline WIM file use this to commit (save) the changes BACK to the WIM file
    DISM.exe /Unmount-Wim /MountDir:C:\OfflineFolderName\Mounted /commit

    Or execute this command to scrap all the changes
    DISM.exe /Unmount-Wim /MountDir:C:\OfflineFolderName\Mounted /discard

    Sean
    The Energized Tech


    Powershell. It's so Easy and it's FREE! Dive in and use it now, It'll take no time. :) http://www.energizedtech.com http://www.itprotoronto.ca
    Tuesday, March 16, 2010 2:37 PM
    Moderator
  • I'm all for Powershell as the end all solution to everything but in some situations I veer away simply because there are prebuilt solutions within Windows to solve the problem.

    I think if "DriverQuery" runs inside Windows XP SP3 then "DRVINST" will as well.  It may be a legacy command.

    Having said that, there are some absolutely astounding things you can do with Powershell.   I know using a GET-WMIOBJECT Win32_pnpentity can pull up a list of all installed Plug and Play devices.  I'm not certain what library can ben accessed to call up the methods to injecting the drivers tho.  

    Any .NET guys know which library to call up the Driver installs?

    Sean


    Powershell. It's so Easy and it's FREE! Dive in and use it now, It'll take no time. :) http://www.energizedtech.com http://www.itprotoronto.ca
    Tuesday, March 16, 2010 3:39 PM
    Moderator
  • This is part of the script we use to perform additional software installations during our Windows 7 imaging process. We make various WMI queries and install different software or drivers based on those queries.

    # Set TIMOUT value. This is the maximum amount of time in milliseconds to wait
    # for a process to complete before continuing the script.
    set-variable -name TIMEOUT -value 300000 -option constant
    
    Write-Host "Installing additional software..."
    
    # Set base path to prefix all installation paths.
    $rPath = "C:\Win7Stage\PostInstall\Silent\"
    
    # Get the computer manufacturer and model from Win32_ComputerSystem.
    $computerSystem = Get-WmiObject win32_computerSystem
    $processor = Get-WmiObject win32_processor
    write-host -NoNewLine "Computer Manufacturer: "
    Write-Host -ForeGroundColor yellow `t $computerSystem.manufacturer
    write-host -NoNewLine "Computer Model: "
    Write-Host -ForeGroundColor yellow `t $computerSystem.model
    write-host -NoNewLine "L2CacheSize: "
    Write-Host -ForeGroundColor yellow `t `t $processor.L2CacheSize
    
    # Initiate new Process and ProcessStartInfo objects.
    $process = New-Object system.Diagnostics.Process
    $si = New-Object System.Diagnostics.ProcessStartInfo
    
    # Define the startProcess function. This function accepts a ProcessStartInfo
    # object, launches that process, and waits for its process id to exit before
    # returning.
    Function startProcess
    {
     param ($startInfo)
     Begin 
     {
      Write-Host ""
      Write-Host "Attempting to install" $startInfo.FileName $startInfo.Arguments
     }
     Process
     {
      $process.StartInfo = $startInfo
      $process.Start()
      $processID = $process.Id
      $process.WaitForExit($TIMEOUT)
     }
     End
     {
      Write-Host ""
     }
    }
    
    # =============================================================================
    # Install software specific to the computer manufacturer
    # =============================================================================
    # Determine if this is a Dell or an HP. We do this by searching the
    # manufacturer variable for the string "dell". If "dell" is found, the
    # installation for Dell OMCI is launched. If "dell" is not found, the
    # computer is assumed to be an HP and the HP CMI installation is launched.
    If ($computerSystem.manufacturer.toLower().contains("dell"))
    {
     #Dell OpenManage Client Instrumentation
     Write-Host "Installing Dell OMCI..."
     $si.FileName = $rPath + "Dell\OMCI\R214519\setup.exe"
     $si.Arguments = "/s /v/qn"
     startProcess $si
     
     #Make changes to BIOS settings for all Dells
     Start-Sleep 5
     
     #Turn Off Dell OMCI Alerts
     (gwmi -namespace root\dellomci dell_IndicationStaticValues) | foreach {$_.MaxDisplayNotifications=0; $_.put()}
    }
    Else
    {
     #Hewlett-Packard Client Management Interface
     Write-Host "Installing HP CMI..."
     $si.FileName = $rPath + "HP\CMI\SP38117\HPCMIProviders.msi"
     $si.Arguments = "/qn"
     startProcess $si
    }

    Saturday, July 17, 2010 1:58 PM

All replies

  • First I would recommend providing as much drivers as possible within your base image. Install afterwards per client can take a lot of time.
    Second you should verify what kind of isntallers you have. The windows "standard" is MSI. You can install MSI packages with MSIexec.exe using the commandline. Parameters will be used to supress reboots and GUI messages (called silent install) and to remove any needed user-interaction (unattended install). For non MSI installers, you should check the documentation of these packages to obtain info on how to install silent AND unattended. This sourceforge link has proven very valuable to me to get this info.

    In a powershellscript you can then call these programs with the invoke cmdlet or by just placing them one after the other. But in both cases all commands will be executed without waiting.
    You can avoid this in many ways, but I would in fact recommend not to use powershellscripts, but batch files or vbs scripts for this :)
    in batch you use start /wait *command*

    MCSA/MCTS/MCP
    Tuesday, March 16, 2010 11:41 AM
  • Thanks for the reply,

    The drivers I have are supplied by Dell so will check with their docs for additional help, I'm not too worried about the time it takes to complete the setup as long as it doesn't run too long as the machines just need to clean for users to check out when needed

    I'm interested to know why you would go with batch files or vbs scripts instead of powershell
    Tuesday, March 16, 2010 1:58 PM
  • Actually what operating system are you dealing with?

    If it's Windows Vista or something newer I think you CAN run the DRVINST command.

    DRVINST C:\DRIVERFOLDER\DRIVERNAME.INF

    Offline .WIM files can have drivers injected to them using DISM.EXE

    DISM.EXE /Mount-wim /WIMFILE:C:\FOLDER\FILENAME.WIM /index:1 /Mountdir:C:\OfflineFoldername\Mounted

    All Drivers in a folder called C:\DRIVERFOLDERNAME (including Subfolders)
    DISM.EXE /IMAGE:C:\OfflineFoldername\Mounted /Add-Driver /driver:C:\DRIVERFOLDERNAME -Recurse

    the Drivers within a Folder called C:\DRIVERFOLDERNAME
    DISM.EXE /IMAGE:C:\OfflineFoldername\Mounted /Add-Driver /driver:C:\DRIVERFOLDERNAME

    A single Driver within a folder called C:\DRIVERFOLDERNAME called Somedriver.inf
    DISM.EXE /IMAGE:C:\OfflineFoldername\Mounted /Add-Driver /driver:C:\DRIVERFOLDERNAME\Somedriver.inf

    When done with the offline WIM file use this to commit (save) the changes BACK to the WIM file
    DISM.exe /Unmount-Wim /MountDir:C:\OfflineFolderName\Mounted /commit

    Or execute this command to scrap all the changes
    DISM.exe /Unmount-Wim /MountDir:C:\OfflineFolderName\Mounted /discard

    Sean
    The Energized Tech


    Powershell. It's so Easy and it's FREE! Dive in and use it now, It'll take no time. :) http://www.energizedtech.com http://www.itprotoronto.ca
    Tuesday, March 16, 2010 2:37 PM
    Moderator
  • Its XP SP3 I am working with, its part necessity part educational as to why I'm looking at powershell
    Tuesday, March 16, 2010 2:44 PM
  • I'm all for Powershell as the end all solution to everything but in some situations I veer away simply because there are prebuilt solutions within Windows to solve the problem.

    I think if "DriverQuery" runs inside Windows XP SP3 then "DRVINST" will as well.  It may be a legacy command.

    Having said that, there are some absolutely astounding things you can do with Powershell.   I know using a GET-WMIOBJECT Win32_pnpentity can pull up a list of all installed Plug and Play devices.  I'm not certain what library can ben accessed to call up the methods to injecting the drivers tho.  

    Any .NET guys know which library to call up the Driver installs?

    Sean


    Powershell. It's so Easy and it's FREE! Dive in and use it now, It'll take no time. :) http://www.energizedtech.com http://www.itprotoronto.ca
    Tuesday, March 16, 2010 3:39 PM
    Moderator
  • This is part of the script we use to perform additional software installations during our Windows 7 imaging process. We make various WMI queries and install different software or drivers based on those queries.

    # Set TIMOUT value. This is the maximum amount of time in milliseconds to wait
    # for a process to complete before continuing the script.
    set-variable -name TIMEOUT -value 300000 -option constant
    
    Write-Host "Installing additional software..."
    
    # Set base path to prefix all installation paths.
    $rPath = "C:\Win7Stage\PostInstall\Silent\"
    
    # Get the computer manufacturer and model from Win32_ComputerSystem.
    $computerSystem = Get-WmiObject win32_computerSystem
    $processor = Get-WmiObject win32_processor
    write-host -NoNewLine "Computer Manufacturer: "
    Write-Host -ForeGroundColor yellow `t $computerSystem.manufacturer
    write-host -NoNewLine "Computer Model: "
    Write-Host -ForeGroundColor yellow `t $computerSystem.model
    write-host -NoNewLine "L2CacheSize: "
    Write-Host -ForeGroundColor yellow `t `t $processor.L2CacheSize
    
    # Initiate new Process and ProcessStartInfo objects.
    $process = New-Object system.Diagnostics.Process
    $si = New-Object System.Diagnostics.ProcessStartInfo
    
    # Define the startProcess function. This function accepts a ProcessStartInfo
    # object, launches that process, and waits for its process id to exit before
    # returning.
    Function startProcess
    {
     param ($startInfo)
     Begin 
     {
      Write-Host ""
      Write-Host "Attempting to install" $startInfo.FileName $startInfo.Arguments
     }
     Process
     {
      $process.StartInfo = $startInfo
      $process.Start()
      $processID = $process.Id
      $process.WaitForExit($TIMEOUT)
     }
     End
     {
      Write-Host ""
     }
    }
    
    # =============================================================================
    # Install software specific to the computer manufacturer
    # =============================================================================
    # Determine if this is a Dell or an HP. We do this by searching the
    # manufacturer variable for the string "dell". If "dell" is found, the
    # installation for Dell OMCI is launched. If "dell" is not found, the
    # computer is assumed to be an HP and the HP CMI installation is launched.
    If ($computerSystem.manufacturer.toLower().contains("dell"))
    {
     #Dell OpenManage Client Instrumentation
     Write-Host "Installing Dell OMCI..."
     $si.FileName = $rPath + "Dell\OMCI\R214519\setup.exe"
     $si.Arguments = "/s /v/qn"
     startProcess $si
     
     #Make changes to BIOS settings for all Dells
     Start-Sleep 5
     
     #Turn Off Dell OMCI Alerts
     (gwmi -namespace root\dellomci dell_IndicationStaticValues) | foreach {$_.MaxDisplayNotifications=0; $_.put()}
    }
    Else
    {
     #Hewlett-Packard Client Management Interface
     Write-Host "Installing HP CMI..."
     $si.FileName = $rPath + "HP\CMI\SP38117\HPCMIProviders.msi"
     $si.Arguments = "/qn"
     startProcess $si
    }

    Saturday, July 17, 2010 1:58 PM