Remove Appx if version less than - powershell

First off, thanks for taking the time to read my issue and hopefully point me in the right direction.
Second, I hate Appxpackages :)
My understanding of how an Appx works is the following, so please correct me if you think I have got it wrong. When a user signs into a PC various windows applications based on Appxpackages will get installed at the current release. For example the calculator could be;
Microsoft.WindowsCalculator_11.2210.0.0_x64__8wekyb3d8bbwe
The user may never sign into that PC again, 6 months down the line there could be a vulnerability discovered in this application and it gets patched with an update. However, this only applies if the user signs in and the store does its job of updating out of date appxpackages.
The issue with this is, if you are in an enterprise environment and you use something like Qualys to scan your clients it will show this vulnerability. Furthermore you could have a mix of users and each user could have a different version.
I'd like to develop a method with powershell to check for the version of the appxpackage for all users and for any user that does not have the currently patched version it uninstalls, I don't believe it is possible to update for a user not signed in.
My idea is to use something along the lines of this
[version]$version=(get-appxpackage -Name *Microsoft.WindowsCalculator* -Allusers).Version
If ($Version -eq [version]"11.2210.0.0")
{
"Minimum version met"
}
ElseIf ($Version -lt [version]"11.2210.0.0")
{
Remove-AppxPackage -Package $version -Allusers
}
I'm certain it won't work, but I can't think how to deal with it. I know I can't use $version as that just finds all versions, so for the else-if I were to user $version it would just remove all versions for everyone.
In the past I have done something similar for the Teams.exe application within Appdata folders for each user. That was much easier to deal with as I know the installer folder in appdata, I could easily query the version number and cycle through each user profile one at a time, but I don't see a way to do this for appxpackages.
Any guidance on this would be really appreciated.

I'm on mobile, so I can't test this.
Have you tried looking at Get-AppxPackageManifest? I can't see the object it returns from the docs, but I'm sure there would be a current version property' or even in Get-AppxPackage
So maybe try
# check for installed, or something version in the output
Get-AppxPackage -Name *Microsoft.WindowsCalculator* | Get-Member
# If there wasn't a property, see if the manifest has one
Get-AppxPackage -Name *Microsoft.WindowsCalculator* | Get-AppxPackageManifest | Get-Member
If there's a property that works the commands would be something like this.
$version = (Get-AppxPackage -Name *Microsoft.WindowsCalculator* | Get-AppxPackageManifest). # fill in property
# you could use a switch statement for this purpose
Switch ($value -Lt 11.2210.0.0)
'true' { Get-AppxPackage -Name *Microsoft.WindowsCalculator* | Remove-AppxPackage -whatif # keep here for testing, and remove -whatif when satisfied}
'false' { Write-Output ' The installed version is $($version), and is not vulnerable}
Try just one user first, and then try the -alluser tag
Hopefully this can help.
Get-Command *appx*

Related

Powershell: Two questions about Get-AppxPackage and the -PackageTypeFilter parameter

I am making a list of app packages installed on my system. In this specific case the ZuneMusic packages. I use the following command:
Get-AppxPackage -AllUsers -PackageTypeFilter Main, Bundle, Resource, Framework |
Where-Object {$_.Name -like "*ZuneMusic*"}
This will get me a list/result with 4 packages. I can see some have IsResourcePackage : True and one has IsBundle : True etc.
It seems this has to do with the -PackageTypeFilter cause if I only use Main is get only one result. I Looked up the parameter -PackageTypeFilter description:
Specifies one or more comma-separated types of packages that the cmdlet gets from the package repository. Valid values are:
Bundle
Framework
Main
Resource
None
Can someone elaborate/explain a bit more what this -PackageTypeFilter parameter does please?
If I want to delete packages of apps that I do not use or want. Do I use all options of this parameter and delete all the results or is one specific option enough?
why dont you just do get-appxpackage -name *zunemusic* -allusers | remove-appxpackage?
dont use -packagetypefilter
the pipeline will get all the returned apps named *zunemusic* and remove them - however, if it floats your boat, specify each package individually
if you remove each package individually, possible future name changes could affect the script and will require manual update if so - probably unlikely though

Verify driver install through powershell

I need to install a driver on a bunch of systems. (it should have come from MS but we are using kace for patching so i cant use wsus to push it out) So i found this oneliner RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 %path to inf%
Next is to put a check into it so it looks if the driver is installed first but I am having trouble finding the driver. I made an assumption that guidid or class from .inf will provide me with the info i need to check.
[Version]
Signature="$Windows NT$"
Class=SmartCard
ClassGuid={990A2BD7-E738-46c7-B26F-1CF8FB9F1391}
Provider=%ProviderName%
CatalogFile=delta.cat
DriverVer=08/11/2015,8.4.9.0"
Get-WmiObject Win32_PnPSignedDriver -Property * | where {$_.ClassGuid -like
"990A2BD7-E738-46c7-B26F-1CF8FB9F1391"}
but I can not find the driver installed. I list all drivers and attempt to scroll through them to find this one and it's not there or it's called something else now.
eventual goal is something like this
if (!(Get-WmiObject Win32_PnPSignedDriver| select devicename, classguid |
where {$_.classguid -like "*990A2BD7-E738-46c7-B26F-1CF8FB9F1391*"})) {echo
do stuff} else { echo dont do stuff}
Any help in being able to identify if the driver is installed or not would be appreciated.
A little googling goes a long way as this has been asked a few times before. Here is a WMIC query against all the installed drivers on the system, then filters out everything except the smartcard class using the classGUID.
Get-WmiObject Win32_PnPSignedDriver| where-object {$_.ClassGUID -eq "{50DD5230-BA8A-11D1-BF5D-0000F805F530}"} |Select *
Here is what got me to my answer if you need additional clarification.
How do I get all the smart card readers on my system via WMI?
https://superuser.com/questions/567927/get-driver-version-via-command-line-windows
https://blogs.technet.microsoft.com/askperf/2012/02/17/useful-wmic-queries/

How to get an environment variable in a Powershell script when it is deployed by SCCM?

I've made a script to automatically change and/or create the default Outlook signature of all the employees in my company.
Technically, it gets the environment variable username where the script is deployed, access to the staff database to get some information regarding this user, then create the 3 different files for the signature by replacing values inside linked docx templates. Quite easy and logical.
After different tests, it is working correctly when you launch the script directly on a computer, either by using Powershell ISE, directly by the CMD or in Visual Studio. But when we tried to deploy it, like it will be, by using SCCM, it can't get any environment variable.
Do any of you have an idea about how to get environment variables in a script when it is deployed by SCCM ?
Here is what I've already tried :
$Name = [Environment]::UserName
$EnvVarUserName = Get-Item Env:\USERNAME
Even stuff like this :
$proc = gwmi win32_process -Filter "Name = 'explorer.exe'"
$report = #()
ForEach ($p in $proc)
{
$temp = "" | Select User
$temp.user = ($p.GetOwner()).User
$report += $temp
}
Thanks in advance and have a nice day y'all !
[EDIT]:
I've found a way of doing this, not the best one, but it works. I get the name of the machine, check the DB where when a laptop is connected to our network it stores the user id and the machine, then get the info in the staff DB.
I will still check for Matt's idea which is pretty interesting and, in a way, more accurate.
Thank you all !
How are you calling the environmental variable? $Env:computernamehas worked for me in scripts pushed out via SCCM before.
Why don't you enumerate the "%SystemDrive%\Users" folder, exclude certain built-in accounts, and handle them all in one batch?
To use the UserName environment variable the script would have to run as the logged-in user, which also implies that all of your users have at least read access to your staff database, which, at least in our environment, would be a big no-no.

How can I find the Microsoft Edge version on Windows 10 in powershell?

I've searched through the SOFTWARE\Classes and SOFTWARE\Microsoft subkeys, but couldn't find anything related to "spartan" or "edge". Given that Edge is still very new, there really isn't much information about this yet.
As an example, this is how I gather the information about the Internet Explorer Version via the registry on a remote machine:
$ieVersion=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $args[0]).OpenSubKey('SOFTWARE\Microsoft\Internet Explorer').GetValue('SvcVersion')
Use the Get-AppxPackage command:
Get-AppxPackage -Name Microsoft.MicrosoftEdge | Foreach Version
The package name is valid on build 10240 but if you are on an earlier build, it might be different. If the above doesn't find the package try -Name *Edge* or -Name *Spartan*.
$productPath = $Env:WinDir + "\SystemApps\Microsoft.MicrosoftEdge_*\MicrosoftEdge.exe"
If(Test-Path $productPath) {
$productProperty = Get-ItemProperty -Path $productPath
Write-Host $productProperty.VersionInfo.ProductVersion
}
Else {
Write-Host "Not find Microsoft Edge."
}
Source How to determine the version of Microsoft Edge browser by PowerShell
For Edge on Chromium above 44 version
powershell:
Get-AppxPackage -Name *MicrosoftEdge.* | Foreach Version
cmd:
powershell "Get-AppxPackage -Name *MicrosoftEdge.* | Foreach Version"
I tested using two commands back to back. I ran from an elevated PowerShell session New-PSSession -ComputerName "The remote PC I was testing this on." and then once the connection was made I ran the Get-AppxPackage -Name Microsoft.MicsrosoftEdge and it pulled down the information, but I think it was more build information. You can also filter it down to version using the Pipe character. The full command looked like this.
Get-AppxPackage -Name Microsoft.MicrosoftEdge | select-object Version
I found this forum and others that lead me to some of the other switches and parameters I did not know about.
How can I find the Microsoft Edge version on Windows 10 in powershell?
I was trying to find an alternate way of remotely finding out what browser version it was. Trying to verify if it is updating regularly. I am still learning. I hope this helps. I found another article that shows me exactly what I am looking for differently without powershell.
https://www.tenforums.com/tutorials/161325-how-find-version-microsoft-edge-chromium-installed.html#option2
You may see multiple versions of Edge installed via Appx-Packages. I would recommend this approach:
$EdgeExe = Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe' "(default)"
$version = (Get-Item $EdgeExe).VersionInfo.ProductVersion

Get Registry Name using powershell

I wanted to loop through registry entries using powershell and uninstall certain MSIs.
I found the answer in this post very simillar to my requirement. However I have a slight different requirement. (I dont want to use UnInstall String)
I get a list of all registries in 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' and I want to use the NAME (i.e. the productcode) of the registry itself.
My Question: How to get the name of the registry.
You need to use Get-ChildItem.
For example, this gives the Name of the key under Uninstall key.
Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Select PSChildName
Update based on the comment:
Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Where-Object {
$_.PSChildName -Eq '{D2B9C003-A3CD-44A0-9DE5-52FE986C03E5}'} | Select PSChildName
You shouldn't really be trolling the registry. The correct way to do this for MSI-based installs is to use MsiEnumProducts to find all the installed MSI products, use the returned product code to get info about their names and versions (MsiGetProductInfo) to see if you want to uninstall them, and then use MsiConfigureProduct and set them to installstate_absent. If you dig around you may find some p/invoke interop code to do this from managed code, that would get you into PowerShell.