Registry Watermark and DriverStore Import

Greetings! This is my first post in the forums, and my first time on powershell.org. I am new to Powershell, however, I understand how powerful and useful it is in the Windows realm. I have the following scenario that I would like to request some assistance/guidance with since my Powershell skills are pretty much non-existent and I am trying to learn as I go.

Scenario: I am trying to write a powershell script that can be run at startup, as system or service, by use of GPO, or manually by an administrator. I would like to script to check for a Windows registry watermark first. If the watermark, exists, that means that the script has already ran and does not to be run again, so essentially the script would end without any action. If the watermark does not exist, I would like for it to create the watermark, then proceed to check the model of the computer. Based upon the what comes after CF-53 in the model name, it would pretty much use a case structure to install the appropriate drivers for the matching model. I will have exported the Windows DriverStore for different variants of the CF-53 and loaded them at C:\Drivers with the following folders within:

CF53mk1Drivers
CF53mk2Drivers
CF53mk3Drivers
CF53mk4Drivers

If the model of the computer began with CF-531, then the script would go through all of the drivers in the folder CF53mk1Drivers and install them recursively, forcing the install even if the publisher cannot be verified. I have drafted up the following code, but have not been able to test it because I have not finished building the driverstore on the different variants.

# Get computer model
$a = (Get-WmiObject -Class Win32_ComputerSystem -Property * | Select-Object -Property Manufacturer, Model)
Write-Host "Manufacturer is: $($a.Manufacturer)" -ForegroudColor Green
Write-Host "Model is: $($a.Model)" -ForegroundColor Green

# Check to see if registry watermark exists
$b = (Test-Path "HKLM:\Test")
If ($b = "False") {
# Add registry watermark if it does not exist
New-Item -Path "HKLM:\Test" -Force
    #Install Driver for Panasonic Toughbook CF 53 MK1
    If $a.Model = "CF-531"{
    Write-Host "Installing drivers for Panasonic Toughbook CF 53 MK1" -ForegroundColor Yellow
    Add-WindowsDriver -Driver "C:\Drivers\CF53mk1Drivers" -Recurse -ForceUnsigned
    }
    #Install Driver for Panasonic Toughbook CF 53 MK2
    If $a.Model = "CF-532"{
    Write-Host "Installing drivers for Panasonic Toughbook CF 53 MK2" -ForegroundColor Yellow
    Add-WindowsDriver -Driver "C:\Drivers\CF53mk2Drivers" -Recurse -ForceUnsigned
    }
    #Install Driver for Panasonic Toughbook CF 53 MK3
    If $a.Model = "CF-533"{
    Write-Host "Installing drivers for Panasonic Toughbook CF 53 MK3" -ForegroundColor Yellow
    Add-WindowsDriver -Driver "C:\Drivers\CF53mk3Drivers" -Recurse -ForceUnsigned
    }
    #Install Driver for Panasonic Toughbook CF 53 MK4
    If $a.Model = "CF-534"{
    Write-Host "Installing drivers for Panasonic Toughbook CF 53 MK4" -ForegroundColor Yellow
    Add-WindowsDriver -Driver "C:\Drivers\CF53mk4Drivers" -Recurse -ForceUnsigned
    }
}
Else{
Write-Host "Drivers for $($a.Model) not found" -ForegroundColor Red
}

If anyone can let me know if I am on the right path, or suggest updates to make it more efficient and work, I would greatly appreciate it!

Respectfully,
John

Of course I have no environment like yours to test, but here is my stab at some suggestions about your script. Note though I left screen out put in, that was just a debug thing see results.

<pre>
Start-Transcript
# Get computer model
$a = (Get-WmiObject -Class Win32_ComputerSystem -Property * | Select-Object -Property Manufacturer, Model)
</pre>

Though you can still use WMI cmdlets as you are doing above, the direction is to use CIM

<pre>
Get-CimInstance -ClassName Cim_ComputerSystem
</pre>

Write-Host really should be avoided in automation tasks, espeically since in a start up script (which you could set to do X or Y before a user ever logs on), no one will be there, in most cases to see it.
Also, unless you are doing the coor thing, you really don’t need Write- anything to send stuff to the screen. That is the default.
So, this…

<pre>
Write-Host 'Installing drivers for Panasonic Toughbook CF 53 MK1'
</pre>

… and this…

<pre>
'Installing drivers for Panasonic Toughbook CF 53 MK1'
</pre>

… do the same thing.

If you are testing, in a logged on session, consider using Write-Verbose, as you can just use the switch when you want to see things on the screen. It has it’s own default color.
or just set Start-Transcript to log your script run and its information

<pre>
Write-Verbose "Manufacturer is: $($a.Manufacturer)"
Write-Verbose "Model is: $($a.Model)"
</pre>

You can do this in line
Check to see if registry watermark exists
$b = (Test-Path “HKLM:\Test”)

This is not corrent ‘=’ is an assignment operator ‘-eq’ is the comparison

<pre>
If ((Test-Path 'HKLM:\Test') -eq $false) 
{

    # Add registry watermark if it does not exist
</pre>

Change this …

    <pre>
    New-Item -Path "HKLM:\Test" -Force
    </pre>

To this

    <pre>
    New-Item -Path hklm:\ -Name 'Test' 
    </pre>

This can be a loop to save yourself all of the if statements.
Default to alway susing single quotes unlees you need variable expansion.
Also, you ‘if statements are not correct’

    <pre>
    'CF-531','CF-532','CF-533','CF-534' | 
    ForEach {
                $Model = $_
                "Processing $Model"
                Switch ($Model)
                {
                    'CF-531' {"Installing $model"}
                    'CF-532' {"Installing $model"}
                    'CF-533' {"Installing $model"}
                    'CF-534' {"Installing $model"}
                    Default {"Drivers for $model not found"}
                }
                
            }

 }
 Else
 {'Key already exists'}


Results 

Processing CF-531
Installing CF-531
Processing CF-532
Installing CF-532
Processing CF-533
Installing CF-533
Processing CF-534
Installing CF-534


Stop-Transcript
</pre>

Note that Add-WindowsDriver only works for offline Windows images (wims). Pnputil works for live Windows images.

postanote,

Thank you so much for the tips. I updated the script for the particular driverstores that I have already built and set the script to run at startup. It seems to work flawlessly. Here is what I ended up with, thanks to you and js:

# Get computer model
$a = Get-CimInstance -ClassName Cim_ComputerSystem
"Manufacturer is: $($a.Manufacturer)"
"Model is: $($a.Model)"

# Check to see if registry watermark exists
If ((Test-Path 'HKLM:\Software\test') -eq $false)
{
# Add registry watermark if it does not exist
New-Item -Path hklm:\Software\ -Name 'test'

# Install drivers using PNPUtil.exe
    'CF-533ALBZBM', 'CF-31WML73LM' |
    ForEach {
                $Model = $_
                "Processing $Model"
                Switch ($Model)
                {
                    'CF-533ALBZBM' {
                    "Installing $model"
                    Get-ChildItem "C:\DriversImport\$model\" -Recurse -Filter "*.inf" |
                    ForEach-Object { PNPUtil.exe /add-driver $_.FullName /Install }
                    }
                    'CF-31WML73LM' {
                    "Installing $model"
                    Get-ChildItem "C:\DriversImport\$model\" -Recurse -Filter "*.inf" |
                    ForEach-Object { PNPUtil.exe /add-driver $_.FullName /Install }
                    }
                    Default {"Drivers for $model not found"}
                }
            }
}
Else
{'Key already exists'}

Do you know of a way to delete all of the subdirectories under C:\DriversImport, excluding the folder corresponding to the model? After that I think I will be all set!

Respectfully,
John