Double driver export script - windows

I'm terrible at scripting, so I would like some help with a script which does the following:
a wmic query:
wmic computersystem get model
Latitude E7450
creates a folder in the root using the query output without spaces:
Latitude_E7450
Then run double driver to backup all the drivers and storing them in the newly created folder:
ddc b /source:"c:\Windows" /target:"c:\Latitude_E7450"

You can get name for the target folder from the WMI Model using powershell, assuming WMI returns this (some OEM units don't),
$dirName = (Get-WmiObject -Class win32_computersystem).Model
Then you can call Double Driver,
& ddc.exe b /source:"C:\Windows" /target:"C:\$dirName"
For a pure powershell solution, see for example this post from Mikael Nyström, "PowerShell is King – Export drivers from Windows"
Export-WindowsDriver -Destination "C:\Drivers\$((Get-WmiObject -Class win32_computersystem).Model)" -Online
This requires Windows 6.3 at least (8.1 or 2012 R2), so use Double Driver for Win 7, if you can still find it. For even more bells and whistles, see "Building Configuration Manager Driver Packages for Windows 7 with PowerShell and Double Driver".

Related

PS: Emulate CCleaner "Uninstall" tool to list programs installed on PC

CCleaner contains a tool to list and then uninstall programs on your PC. This list seems to include applications in a more comprehensive way than a walk through the uninstall registry keys. One example of this, is Atom (the Open Source text editor). This program does not appear in the uninstall registry, and is installed in the AppData folder of the user (I'm not aware of a way to install this for all users without building a custom package).
I wrote a script that installs and updates certain software packages on a regular basis. This makes it easy for me to keep them up to date without visiting a dozen or so websites every week or building a custom installer every time I want to update them (they don't auto-update like Chrome or Firefox). Therefore, I need a list that I can create dynamically and use to check for updates and if I need to execute the installer.
So my question is: How do I emulate what CCleaner does when it creates its list of programs for uninstalling -- programmatically? I can execute the GUI and navigate to the uninstall tool and click "save to text file" but that isn't dynamic. Any answer that allows me to capture (in a Powershell script) the same list of applications that CCleaner generates in the uninstall tool will be acceptable.
You can use Get-Package to list installed programs as well. It will list Atom. You may need to combine the registry approach with Get-Package in the case it doesn't show all.
Get-Package | Where-Object name -like *atom*
Name Version Source ProviderName
---- ------- ------ ------------
Atom 1.53.0 Programs
What you are asking for used to be done with Get-CimInstance, but that comes at a cost and as you pointed out is no longer accurate. It used to be a WMI command. Now CIM. It is not a fast command, more on that later.
Get-CimInstance win32_product
The cost is Get-CimInstance can return incomplete data. It also runs a consistency check on all applications and performs automatic and silent repairs. Yes, when you run this command, it automatically runs a consistency check on all applications and performs automatic and silent repairs. That is why this simple command is so slow to report back.
Microsoft's documentation on this: Link Here
So we do not use that anymore, now what? What you are looking for is gathering the information from both 32 and 64 bit installers that looks like this and must be done, I do it first, always.
$installedApplications = #()
$installedApplications+= Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" # 32 Bit
$installedApplications+= Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" # 64 Bit
One caveat to the above is that the above method will return a ton more elements than the Win32_Product command does. It will have things such as Service Packs, Office Updates, Language Packs, etc. You will most likely need to filter out things you aren’t interested in, though you shouldn't have an issue using PowerShell to filter results.
To complete the answer to your question, how do you quantify data from installers regardless of their install location? Specifically finding the userprofile\AppData install information. The good news is these applications have their installation information documented in the registry as well, under HKEY_CURRENT_USER instead of HKEY_LOCAL_MACHINE. What this means is every user's install location information is sitting in the registry hive under their profile, for instance c:\users\inet\NTUSER.DAT.
What else needs to be said about this;
If a user is logged in this can be accessed by any other admin user on the system by using the HKEY_USERS\$ACCOUNT_SID key.
If a user is not logged in, the hive can be manually mounted using REG LOAD
If a user's registry hive is already loaded it cannot be loaded a second time and will give you the obligatory "this file is being used by another process."
So how do we get what you are asking for, which is to replicate the "full install data" for the device, and not just what's in the 32 and 64bit directories?
This is what I use, if one so chooses you can pipe the info to CSV/HTML/etc...
$installedApplications = #()
$installedApplications+= Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$installedApplications+= Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
$32BitPath = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$64BitPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
$tigerStripes= Get-CimInstance Win32_UserProfile | Select LocalPath, SID, Loaded, Special | Where {$_.SID -like "S-1-5-21-*"}
$unavailableProfiles = $tigerStripes| Where {$_.Loaded -eq $true}
$availableProfiles = $tigerStripes| Where {$_.Loaded -eq $false}
#Mounted
$unavailableProfiles | % {
$installedApplications += Get-ItemProperty -Path "Registry::\HKEY_USERS\$($_.SID)\$32BitPath"
$installedApplications += Get-ItemProperty -Path "Registry::\HKEY_USERS\$($_.SID)\$64BitPath"
}
#Unmounted
$availableProfiles | % {
#Mount Hive
$Hive = "$($_.LocalPath)\NTUSER.DAT"
if (Test-Path $Hive) {
REG LOAD HKU\temp $Hive
$installedApplications += Get-ItemProperty -Path "Registry::\HKEY_USERS\temp\$32BitPath"
$installedApplications += Get-ItemProperty -Path "Registry::\HKEY_USERS\temp\$64BitPath"
#This lets the hive be unmounted, using a manual Get-Content
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
REG UNLOAD HKU\temp
} else {
Write-Warning "Unable to access registry at $Hive"
}
}
$installedApplications

Uninstalling Systrack from CMD

So I'm trying to remotely uninstall the application SysTrack using:
wmic product where "description='Systems Management Agent' " uninstall
but for some reason it can't find the product. Doing a
product get name
from the wmic:root console, I don't see it listed. I'm wondering why the wmic can't get all the list of installed programs? It shows up on programs and features list, but now when I run that wmi command. I am a domain admin so the credentials should be a problem (the folder in the Program Files(x86) folder for SysTrack does have a lock on it though, but I can access)
Side note: I really wish there was a way to remotely just view that programs and features menu. Would be incredibly handy for the tasks I've been doing lately.
try;
wmic product where "name like 'Systems Management Agent'" call uninstall /nointeractive
it should work.
Try this in powershell ise. It will take a list of hostnames from a text file and uninstall the application. Edit the path for your local directory and text file name.
This script is 2 lines. Everything before $app.Uninstall() is on one line and then $app.Uninstall() is the 2nd line.
$app = Get-WmiObject -Class Win32_Product -ComputerName (Get-Content -Path "C:\Users\MYUSERNAME\Documents\PowerShell\servers.txt") | Where-Object {$_.Name -match “Systems Management Agent”}
$app.Uninstall()

Windows Powershell command line equivalent of dd

I am writing a Powershell script to make a raw copy of a drive and I have been unable to find a way to complete this.
On Linux, I would use 'dd' to perform this copy.
There are a handful of tools that can do this on Windows but none that I can control directly from the command line. (All have GUI interfaces)
Is there a method to make a physical copy of a drive through Powershell?
Thanks.
I've been trying to do this for a while myself and I finally found a good answer.
Git for windows ships with the whole set of GNU core utilities (updated vs what you can find separately) including dd!
Just install Git for Windows or extract the portable version, from there inside of the install directory in git\usr\bin\ you will find the binaries for all of the GNU utils including dd (tested working)
Some further notes on usage in windows since \dev\sda\ isn't a thing:
$DiskDrives = Gwmi Win32_diskdrive | select DeviceID,BytesPerSector,Index,Caption,InterfaceType,Size,TotalSectors,SerialNumber | Out-GridView -OutputMode Multiple -Title 'Select Source Drive(s)'
$BaseOutputPath = 'D:\'
$DiskDrives | %{
. ('C:\Program Files\Git\usr\bin\dd.exe if={0} of={1} bs={2}' -f $_.DeviceID,(-join($BaseOutputPath,(-
join($Env:ComputerName,$_.Index)),'.img')),$_.BytesPerSector)
}
The included filename logic is just a placeholder, you can replace that parenthetical with a call to Read-Host if you want it to prompt you for the filename/path.
It is a bit annoying but you really do have to use WMI as the values returned by Get-Disk don't seem to work.
You might already know that cygwin on Windows supports some Linux commands including dd. I have used it on several occasions to copy disks and load ISOs to USB and it works perfectly.
Windows 10 comes with linux now. Windows Subsystem for Linux. You can enable it as a feature. You can even get WSL 2 with the real kernel in 1903 & 1909: https://devblogs.microsoft.com/commandline/whats-new-in-the-windows-subsystem-for-linux-september-2020/
Get-CimInstance -ClassName Win32_DiskDrive | Format-List -Property DeviceID,BytesPerSector,Index,Caption,InterfaceType,Size,TotalSectors,SerialNumber
Following up #Chirishman answer, for Powershell 7.2, The Gwmi may missing from the powershell.
The alternative command to get the DeviceId and other info is available as above.
Then you can use dd if={DeviceId} of=<target_file>.

How to run an application as shell replacement on Windows 10 Enterprise

I need to create a special account on a computer running Windows 10 Enterprise. This account would launch an application directly on login instead of the default shell and exiting the application should force the computer to restart.
I was able to do this easily on Windows 8.1 Embedded Industry Pro using the configuration console and lockdown features.
Now, on Windows 10 I try to follow the two tutorials on technet WESL_UserSetting and Set up a kiosk on Windows 10 Pro, Enterprise, or Education
However, neither of the tutorials work. I have managed to execute the scripts described in them but they have no effect (I've modified them so they do not remove the shells set).
Finally I've ended up with the following code:
$COMPUTER = "localhost"
$NAMESPACE = "root\standardcimv2\embedded"
$ACCOUNT_NAME = "cmp"
$ShellLauncherClass = [wmiclass]"\\$COMPUTER\${NAMESPACE}:WESL_UserSetting"
$NTUserObject = New-Object System.Security.Principal.NTAccount($ACCOUNT_NAME)
$NTUserSID = $NTUserObject.Translate([System.Security.Principal.SecurityIdentifier]).Value
$NTUser_Shell = Get-WmiObject -namespace $NAMESPACE -computer $COMPUTER -class WESL_UserSetting |
where {$_.Sid -eq $NTUserSID}
if ($NTUser_Shell) {
"`Custom shell already set for [$ACCOUNT_NAME] removing it"
$ShellLauncherClass.RemoveCustomShell($NTUserSID)
}
$restart_shell = 0
$restart_device = 1
$shutdown_device = 2
$ShellLauncherClass.SetCustomShell($NTUserSID, "cmd.exe", ($null), ($null), $restart_device)
"`nCurrent settings for custom shells:"
Get-WmiObject -namespace $NAMESPACE -computer $COMPUTER -class WESL_UserSetting | Select Sid, Shell, DefaultAction
Executing this script in an admin powershell produces the desired output:
Custom shell already set for [cmp] removing it
Current settings for custom shells:
Sid Shell DefaultAction
--- ----- -------------
S-1-5-21-3842421150-1098587697-2315725148-1002 cmd.exe 1
However logging as the 'cmp' user simply shows the standard Windows 10 shell.
What should I change in order to be able to run a program instead of a standard shell?
I had the same problem right now. And yes, Microsoft has changed the way to do a shell replacement. You can install and use the Embedded Shell Launcher to customize windows as you like it for kiosk mode. But this is only available for Enterprise and Education.
If you don't want to buy the Enterprise version you can use the already known registry locations in HKCU and HKLM. https://msdn.microsoft.com/en-us/library/ms838576(v=WinEmbedded.5).aspx
But wait, oh no since Windows 10 it is only possible to use Microsoft signed applications, so your normal .net application isn't started and the screen keeps being black after login. But we've figured out a workaround.
Just use a Batch-File as bootstrapping. If you set the registry keys you like to a Batch-File and the Batch-File starts the real application, then it works like a charm.
#echo off
echo Bootstrapping, please wait ...
start /b "Bootstrap" "C:\vmwatcher\VMViewClientWatcher.exe"
Have you tried changing the users shell?
https://msdn.microsoft.com/en-us/library/ms838576(v=WinEmbedded.5).aspx
There are a few registry keys you need to set. First one enables the ability to give the user a unique shell, the second one defines the executable that starts instead of explorer.
I wanted to do something similar, and I borrowed heavily from other answers, but none of them were a complete working answer for me. Here's what I ended up doing.
Create a new user account
Setup the following vbs script (largely inspired by this thread) to launch the shell application and name it something like "launch.vbs"
set oShell=createobject("wscript.shell")
sCmd="d:\launchbox\launchbox.exe"
oShell.run sCmd,,true 'true forces it to wait for process to finish
sCmd="shutdown /r /t 0"
oShell.run sCmd
Login as the new user
Run regedit
Add a new string value named Shell to HKEY_Current_User\Software\Microsoft\Windows NT\CurrentVersion\Winlogon with a value of the command that you need to run to execute your script:
wscript d:\launchbox\launch.vbs
Logoff and log back on as the user to see it in action
I battled with this one myself. If you look at the notes for Windows 10 Shell Launcher, it only works in the Enterprise or Education version. If you try using this in Home or Pro versions it simply boots to a blank screen. Using the same script in Enterprise, I confirmed works perfectly...
I think you set up correctly the custom shell for the user, but maybe you need to activate the ShellLanuncher behaviour.
Try this (at the end of your script):
$ShellLauncherClass.SetEnabled($TRUE)
This way the standard windows 10 shell is not launched when you log on with the other account, but (at least in my case) the command line does not start and the result is a black screen.
You can still run the task manager and run a new task from there, but I don't understand why the command line does not automatically start.
I ran into the same issue, and that's because the Script from TechNet on how to configure ShellLauncher actually enables, then disables the same Shell!
# Enable Shell Launcher
$ShellLauncherClass.SetEnabled($TRUE)
$IsShellLauncherEnabled = $ShellLauncherClass.IsEnabled()
"`nEnabled is set to " + $IsShellLauncherEnabled.Enabled
# Remove the new custom shells.
$ShellLauncherClass.RemoveCustomShell($Admins_SID)
$ShellLauncherClass.RemoveCustomShell($Cashier_SID)
# Disable Shell Launcher
$ShellLauncherClass.SetEnabled($FALSE)
$IsShellLauncherEnabled = $ShellLauncherClass.IsEnabled()
"`nEnabled is set to " + $IsShellLauncherEnabled.Enabled
I was lazily just copying and pasting the code and expected it to work.
If you comment out the final ten lines, this process will work.
Remember Kids: don't just copy and paste code from Strangers!
I want to begin by apologizing for commenting on a very old thread.
I have struggled for the past 6 months trying to get a custom app to run as a default shell, and retain administrator rights. Like many people, these scripts and/or commands just weren't working, and I needed something quick, effective and EASY!
Simply replacing the "explorer.exe" (HKLM\SOFTWARE\Microsoft\Window NT\Winlogon\Shell) with a custom app location provided a black screen.
A much simpler way, and it works great, was to create a BATCH script to call the custom app through elevated powershell...
powershell -nologo -noprofile -executionpolicy bypass -command "start-process -verb 'runas' -filepath <full path of custom app executable>"
By replacing "explorer.exe" with this batch script I was able to successfully create a kiosk style lockdown under Windows 10 PRO with a non-UWP app.
My fist attempt to help where I have received much. Not a complete answer, but maybe enough to get you to your destination. This worked on my "Kiosk" app which is on "my" Windows 10 Enterprise system which was built specifically for my app. It will set your "shell" to start on system startup and then start your click once program. Hope this helps.
Imports System.Threading
Public Class Form1
# Path to your ClickOnce app
Dim startPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Programs) _
& '"\"' & '"remaining path to your app"' & '".appref-ms"'
# Path to your shell which is also a clickonce app(this one)
Dim spath As String = Application.StartupPath & '"\"' & My.Application.Info.AssemblyName _
& '".exe"'
# This sets the registry to start your shell which in turn starts your app.
# I did this so that if the app is closed, they see the shell background.
# You can add controls to your shell to restart the app, shutdown....
#Just be cautious, make sure your app is 100% done and updates on it's own before you
# disable the ability to get back to windows explorer.
# Other wise you could have a very bad day.
My.Computer.Registry.SetValue('"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\ _
CurrentVersion\Winlogon"', '"Shell"', spath)
Thread.Sleep(500)
Process.Start(startPath)
End Class
You can create a Provisioning Package using Windows Configuration Designer.
The gui will help in creating a simple shell replacement when you choose 'provision kiosk devices'

Scan for new hardware using a bat file?

I have a batch installer that overrides my usb devices drivers.
how can I force my windows to scan for hardware changes using a batch file?
START /WAIT RunDll32.exe Syssetup.dll,UpdatePnpDeviceDrivers
1 The best way I found is:
powershell -windowstyle hidden -command "& {\"rescan\" | diskpart}"
For the detail, you can refer to this link :"Use the rescan command to rescan all I/O buses and cause any new disks that have been added to the computer to be discovered."
For Windows 2008/7 and above, the powershell and diskpart is shipped with OS.
Or just run it without powershell:
echo rescan | diskpart
2 The other way is use the MS command line tool, Devcon, which you have to download it first
You can use it to do a lot of things, including enable/disable/rescan all kind of device(not only disk), update device driver, ... even on the remote machine.
You also can see the source code of it in this link
Windows 10 ships with PnPUtil.exe. Run pnputil.exe /scan-devices from administrative command prompt.
https://serverfault.com/a/1060172/365042

Resources