I have a script that returns Version numbers for 3rd Party software running on our Domain. Java, chrome, etc to ensure we are up to date.
This is all working OK.
However, I am trying to use:
Get-AppxPackage -Name Microsoft.MicrosoftEdge | select-object Version
within a remote Powershell session or 'invoke-command' but it is returning no results,
the command works fine if locally, and also when RDP'd onto the remote machine.
How can i use this cmdlet remotely to check Edge is version compliant?
Many Thanks.
EDIT:
import-module activedirectory
$workstations = Get-ADComputer -Filter "OperatingSystem -like 'Windows 10 *'" -Property * | select name -ExpandProperty Name
foreach ($workstation in $workstations)
{
$session = New-PSSession -Computername $workstation
$resultofsession = Invoke-Command -Session $Session -ScriptBlock{
$Path="HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$path2 = "HKLM:\SOFTWARE\Microsoft\Internet Explorer\"
$java = Get-ItemProperty $Path | Select-Object DisplayName, DisplayVersion | where displayname -like "java*"
$chrome = Get-ItemProperty $path | Select-Object DisplayName, DisplayVersion | where displayname -ceq "Google Chrome"
$adobe = Get-ItemProperty $path | Select-Object DisplayName, DisplayVersion | where displayname -ceq "Adobe Acrobat Reader DC"
$edge = Get-AppxPackage -Name Microsoft.MicrosoftEdge | select-object Version
$ie = get-itemProperty $path2
$Object = New-Object PSObject -property #{
'chrome' = "CHROME: " + $chrome.displayversion + ","
'edge' = "EDGE: " + $edge + ","
'ie' = "IE: " + $ie.svcVersion + ","
'java' = "JAVA: " + $java.Displayversion + ","
'adobe' = "ADOBE: " + $adobe.displayversion + ","
'hostname' = hostname
}
Write-output $object
}
remove-pssession $session
write-output $resultofsession | format-table -HideTableHeaders -autosize -force | Out-File "C:\web\Version.txt" -append
}
Get-AppxPackage will return only information for the current users profile (in this case, the account running the script). You likely need to add the -AllUsers switch, but note this will return a result for each user logged in (and they may have different versions). You can use the -user parameter to specify a specific user.
AppX packages are only updated for the user profile when they log in, hence why different users can have different versions of an app on the same workstation. Assuming everything works as expected, the app should be updated when the user next logs in.
Try the following to return the version number for each user ID:
$edge = Get-AppxPackage -AllUsers -Name Microsoft.MicrosoftEdge | select-object #{N="User"; E={$_.packageUserInformation.UserSecurityId.Username}},Version
Example output:
User Version
---- -------
test 42.17127.1.0
S-1-5-18 44.17763.1.0
jacob 44.18252.1000.0
Related
This question already has answers here:
Check if a Registry Path Exists in Remote Machine
(4 answers)
Test if registry value exists
(13 answers)
Closed 3 months ago.
I've been trying to create a script that checks which applications are installed on a remote server. So far I've been able to get it working to do the job when everything is in place.
However, one of my servers are a bit broken and the "uninstall" registry key is missing from the registry.
So before doing Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" and Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" I want to check if the registry key is present and if that isn't the case, I wish to run Get-WmiObject -Query "select * from win32_product"
Currently when I run it on the machine that is missing the "Uninstall" registry key I get
Cannot find path 'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall' because it does not exist.
+ CategoryInfo : ObjectNotFound: (HKEY_LOCAL_MACH...rsion\Uninstall:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
+ PSComputerName : ServerName001
Current script:
# Change to computer you wish to search.
$ComputerName = "ServerName001"
$ScriptPath = Get-Location
$GetWmiObject_Win32Product = $ScriptPath.ToString() + $ComputerName + "_Get-WmiObject-win32_Product.csv"
$GetItemProperty = $ScriptPath.ToString() + $ComputerName + "_Get-ItemProperty.csv"
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
$directoryInfo64bit = Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall | Measure-Object
$directoryInfo32bit = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Measure-Object
$Apps = #()
if($directoryInfo64bit.count -eq 0){
Write-Output "No 64bit Uninstall folder"
}else{
$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
}
if($directoryInfo32bit.count -eq 0){
Write-Output "No 32bit Uninstall folder"
}else{
$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
}
$Apps | Select-Object -Property DisplayName, Publisher, DisplayVersion, InstallDate, InstallLocation, PSComputerName
} | Export-Csv -Path $GetItemProperty -NoTypeInformation -Encoding utf8
Get-WmiObject -Query "select * from win32_product" -ComputerName $ComputerName | Select-Object -Property Name, Vendor, Version, PSComputerName | Export-Csv -Path $GetWmiObject_Win32Product -NoTypeInformation -Encoding utf8
I have script that checks every 24 hours locally on server the status of all backup jobs along more details.
I want that script to check all my servers, lets say: "SRV1", "SRV2", "SRV3"
How can i manage that?
Here's the script:
$date = (Get-Date).AddHours(-24)
$sessions = Get-VBRComputerBackupJobSession
foreach ($PBackup_job in (Get-VBRComputerBackupJob | Select Name)) {
$PBackup_job_name = $PBackup_job.Name
write "------------ Physical Server Backup Job Name : $PBackup_job_name ------------"
$sessions | where {$_.CreationTime -ge $date} | sort CreationTime | Select CreationTime, endtime, result, state | Format-Table
}
Although I cannot test this myself, I think you could do that using Invoke-Command like below:
$servers = "SRV1", "SRV2", "SRV3"
# set the credentials for admin access on the servers
$cred = Get-Credential 'Please enter your admin credentials'
$result = Invoke-Command -ComputerName $servers -Credential $cred -ScriptBlock {
$date = (Get-Date).AddHours(-24).Date
$sessions = Get-VBRComputerBackupJobSession
foreach ($PBackup_job in (Get-VBRComputerBackupJob)) {
$sessions | Where-Object {$_.CreationTime -ge $date} |
Sort-Object CreationTime |
Select-Object #{Name = 'Server'; Expression = {$env:COMPUTERNAME}},
#{Name = 'BackupJobName'; Expression = {$PBackup_job.Name}},
CreationTime, endtime, result, state
}
}
# remove the extra properties PowerShell added and save to CSV
$result = $result | Select-Object * -ExcludeProperty PS*, RunSpaceId
# output on screen
$result | Format-Table -AutoSize
# write to file
$result | Export-Csv -Path 'X:\Somewhere\BackupJobs.csv' -NoTypeInformation
I have downloaded Get-WindowsAutoPilotInfo and placed on network share. I am trying to use it as a repository to run the script on mulitple pcs remote. But I canĀ“t get it to work it says my reposity doesnt exist, but if I do Get-PsRepository I get the Installation Policy "Trusted" and the correct Source Location.
So I most get the SerialNumber which works, then hardwarehash (not working), and also GroupTag (working on this later when I've dealt with Hardware hash problem).
"Warning: Unable to find repository and therefor says Get-WindowsAutoPilotInfot is not reconginsed as name of cmdlet,function,script ...
Do you have any ideas what I do wrong?
Get-PSRepository
Install-Script -Repository \\Networkshare\--\---\Scripts\GetHardWareHash -Name "Get-WindowsAutoPilotInfo" -Scope AllUsers -Force
$Info = Get-WindowsAutoPilotInfo | Select-Object -ExpandProperty 'Hardware Hash'
$SerialNumber = Get-WmiObject win32_bios | Select-Object -ExpandProperty SerialNumber
$Model = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty Model
$addInfo = #(
$Info,
$Model,
$env:COMPUTERNAME
$SerialNumber
)
# Concert $addInfo to a PSObject for easier exporting to CSV.
$addInfoObject = [PSCustomObject]#{
Info = $Info
Model = $Model
ComputerName = $env:COMPUTERNAME
SerialNumber = $SerialNumber
}
$addInfo | Add-Content \\MyPath\AutoPilot $SerialNumber.log
# Define CSV names
$csvNameInfo = "HashFilesCollected" + ".csv"
$csvNameAddInfo = "AutoPilot " + $SerialNumber + ".csv"
# Export to CSV
$Info | Add-Content \\MyPath\$csvNameInfo
$addInfoObject | ConvertTo-Csv -NoTypeInformation -Delimiter ";" | Select-Object -Skip 1 | Add-Content \\MyPath\$csvNameAddInfo
I am trying to get a list of PC's where the name is equal to LN-M* and then from the reults filter out the ones which have a ReleaseID (Version of Windows) of 1703
Powershell -
this is a list of the variables i will be using
$ReleaseID = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ReleaseID).ReleaseID
$ComputerName = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName" -Name ComputerName).ComputerName
This is to filter the machines by name
$Threshold = (Get-Date).AddDays(-400)
$DesktopPC = Get-ADComputer -Filter * -Properties Name |
where (
$_.name -Like "LN-M*"
)
$results = $DesktopPC | select name
These are the results I hope to get
ForEach-Object {$results -eq
$_.ReleaseID -eq 1703
$ComputerName.Name
}
The basic example code below will do what you're asking for machines that are online and accessible. You'll need to add error checking and validation logic.
$targetMachines = New-Object System.Collections.ArrayList
#Filter by name right in your AD query instead of getting all computer objects
$allMachines = Get-ADComputer -Filter 'Name -like "LN-M*"'
$allMachines | foreach {
$dnsHostname = $_.DNSHostName
# The remote registry service will need to be running on the the target machine
$registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$dnsHostname)
$key = $registry.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion")
$releaseID = $key.GetValue("ReleaseID")
if ($releaseID -eq 1703)
{
$targetMachines.Add($dnsHostname) | Out-Null
}
}
# These are the machines you are looking for (with Jedi hand wave)
$targetMachines
So I've been over at
https://blogs.technet.microsoft.com/heyscriptingguy/2013/11/15/use-powershell-to-find-installed-software/
trying to use this to get a list of installed programs on a remote machine. I already started the WinRM remotely via PS, and am using the command
Invoke-Command -cn MC-PKS-MCARDH-L -ScriptBlock {
Get-ItemProperty HKLM:\Software\Wow6432Node\* |
select PSPath, PSParentPath, PSChildName
}
The primary use of this is to get the Adobe versions of programs on the client's PC, but for some reason this doesn't return many of the folders. It just returns HP, ESRI, Malwarebytes, and a few others:
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Wow6432Node\ESRI
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Wow6432Node
PSChildName : ESRI
PSComputerName : mc-pks-mcardh-l
RunspaceId : 76050648-eec5-4e90-960d-872264a894d4
PSShowComputerName : True
Any reason this is? I tried using the one from the page I linked:
HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*
but Adobe Reader doesn't even show up on that list.
I'm an AD Admin on the domain so why is it not showing all the folders? I'm looking via regedit now on the test machin and theres a folder called Adobe.
I'd recommend using, or at least trying, WMI:
Get-WmiObject -Class Win32_Product | Select-Object -Property Name, Vendor, Version | Format-Table;
You can also specify -ComputerName to query a remote machine.
To list all properties for dev. purposes, try:
Get-WmiObject -Class Win32_Product | Format-List -Property *;
Good luck!
--- ALTERNATIVELY, please try:
[String] $strKey = '';
[String] $strSubKey = '';
[PSCustomObject] $objData = $null;
#( 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' ) | Foreach-Object {
$strKey = $_;
Get-ChildItem -Path $strKey | Select-Object -ExpandProperty PSChildName | Foreach-Object {
$strSubKey = $_;
$objData = Get-ItemProperty -LiteralPath (Join-Path -Path $strKey -ChildPath $strSubKey) | Select-Object -Property DisplayName, DisplayVersion;
if ( $objData.DisplayName -ne $null ) {
Write-Output -InputObject $objData;
} #if
} #Foreach-Object
} #Foreach-Object