Inventory Query for Chrome Extensions?
With the news of the Cisco Webex Chrome plugin having a fairly massive vulnerability (source, summary article), I am interested to know which machines in our environment might have this plugin, as well as other plugins.
Is there any string, in the registry or file system, that could reliably be used as a PDQ Inventory query to see what Chrome plugins are installed?
(I understand Chrome updates plugins automatically, but I still think there is value in knowing which are installed in our environment. We are not using any of Google's ADMX templates to block extensions, but even if we did, I am sure Cisco Webex would be on the allow list)
Comments
From the plugins documentation, you could possibly use a registry scanner to see if anything gets picked up in here:
HKEY_LOCAL_MACHINE\Software\Google\Chrome\Extensions
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Google\Chrome\Extensions
I actually checked both of those locations already on a machine with quite a few extensions, and oddly none were listed.
Can confirm the same on my machine. It seems the extensions I have installed from the webstore don't show in the registry. Must be in the filesystem somewhere. I'll try and track them down.
There may just not be a good way to do this. I am sure I could use the presence of a file or folder to confirm if one was installed, but to actually get a easy to read and consume list - might be difficult.
Nah. I found them. It's just a simple matter of using powershell to tranverse the folders, grab manifest.json and extract the "Name" from each file and return it to you. I'm almost done. Bare with me a bit here.
Couple caveats to this approach, if the extension has multiple versions, this won't traverse the folder correctly. It'll take a little bit of work to get that functionality, but I can add it if you want.
You should be able to package this up, and send the output to Output.log in a Powershell step. Let me know if you need help with that. I know its not Inventory.....but it is what it is. Though, you could put the ps1 file on a fileshare and dot source it as a remote command in Inventory against a collection of machines. That'll return the results to the results window of the remote command.
I hated the format. Updated it to include Name AND Version as an object for readability
Example Output:
Ok, last update. Promise. Script now traverses extensions with multiple versions
Could you please help me with the packaging into a powershell file. I would like to run it on all computers that PDQ has in inventory and create a log.
Copy all the text and save it as a file with a .ps1 extension. For example Get-ChromeExtensions.ps1
Will this work on the Enterprise version?
That's what I'm deploying, so yes. It does.
The output is different. Can I send you a text file?
Sure. Just post the contents here.
PS C:\Users\testr> $targetdir = "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Extensions"
$extensions = Get-ChildItem $targetdir
Foreach($ext in $extensions){
Set-Location $targetdir\$ext -ErrorAction SilentlyContinue
$folders = (Get-ChildItem).Name
Foreach($folder in $folders){
Set-Location $folder -ErrorAction SilentlyContinue
$json = Get-Content manifest.json | ConvertFrom-Json
$obj = New-Object System.Object
$obj | Add-Member -MemberType NoteProperty -Name Name -Value $json.name
$obj | Add-Member -MemberType NoteProperty -Name Version -Value $json.version
Write-Output $obj
}
}
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
Name Version
---- -------
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
ConvertFrom-Json : Invalid object passed in, ':' or '}' expected. (1): {
At line:17 char:37
+ $json = Get-Content manifest.json | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
PS C:\Users\tese\AppData\Local\Google\Chrome\User Data\Default\Extensions\pkedcjkdefgpdelpbcmbmeomcjbeemfm\5516.1005.0.3_0>
Very interesting. What version of Powershell do you have? Post the output of $PSVersionTable
Also please tell me if you have .Net installed and what versions? The cmdlet uses a .Net class inside itself to work properly. So knowing, those two pieces of information I can move forward with assisting.
I just deployed the latest version of Chrome Enterprise to my workstation, as I hadn't in a little while, and re-tested, and my output is still good. I can't re-create your error!
PSVersion 3.0
.NET 4.6.1
Definitely in the correct neighborhood as far as that goes. Try adding -Raw to the Get-Content call on line 17:
This worked.
$json = Get-Content manifest.json -Raw| ConvertFrom-Json
Perfect. I pushed the change to git on my end incase someone stumbles across it on the interwebs. Thanks for the bug report!
Is there any way to determine the real name of the MSG_appName?
There might be. I'd have to toy with it and see if I can find it. I know they are related to google's fleet of things like Docs, Mail, etc.
For one who is PowerShell illiterate (almost), is there a way to do this search in Inventory? Through basic filters?
If not, any additional advise for someone who really doesn't use PS would be nice because I really want to see if any of my users have this WebEx extension.
No there's really not, unfortunately.
Thanks.
We now have a PowerShell Scanner that gathers an inventory of Google Chrome Extensions: https://github.com/pdq/PowerShell-Scanners/tree/master/PowerShell%20Scanners/Google%20Chrome%20Extensions
That scanner has been replaced by this one:
https://github.com/pdq/PowerShell-Scanners/tree/master/PowerShell%20Scanners/Chromium-based%20Browser%20Extensions