check if process is running with only Path provided - windows

I want to check in Powershell if a process is running with only providing the process's path.
As example, the path to the .exe is "C:\Users\Administrator\Desktop\1\hello.exe".
However, there are also multiple .exe's with the same name, just in a different path:
"C:\Users\Administrator\Desktop\1\hello.exe"
"C:\Users\Administrator\Desktop\2\hello.exe"
"C:\Users\Administrator\Desktop\3\hello.exe"
So I can not just do Get-Process "hello".
How can I find out if a process is running by providing a Path, instead of a process name? It also should return the PID of the specific process.
Get-Process sadly does not even shows you the path to the process.

You can filter by Path and select Id:
Get-Process | Where-Object {$_.Path -EQ "C:\Users\Administrator\Desktop\1\hello.exe"} | Select-Object Id
By the way:
Get-Process sadly does not even shows you the path to the process.
It does, if you ask it to (it returns an object like all those commands do, and it has a default selection of properties to list but that doesn't mean you can't access the remaining properties by specifically selecting them):
Get-Process explorer | Select-Object Path
(or use Select-Object * to see all available properties)
It appears you haven't yet understood how PowerShell objects work, so I'd recommend you to check out some tutorials about this topic, for instance this article about selecting and filtering and this one that goes more into detail about the filtering options.

Related

How to show all the available options for a PowerShell command?

For example, this command:
get-netadapter -name "WI-FI"
shows my WIFI network adapter's details with 5 columns of information about it.
but if i do this:
(get-netadapter -name "WI-FI").
and then press tab, I can see a whole lot more information about it that show up after the dot.
now this is only a simple example, there are many more commands like that which by default only show a few columns of information.
what is the universal way of showing all of the available information for each command, like all of the available commands that go after the . in the example above and with their output? I want to show them in console in a nice way like with ft -wrap if possible so I can quickly get a general idea of what information is accessible to me to work with.
I use latest version of PowerShell (7.4 preview) and Windows 11
p.s sometimes pressing tab doesn't work, like in this example:
(get-bitlockervolume -MountPoint $env:SystemDrive).
but we can still use ProtectionStatus after the dot
I usually use command | gm (gm is an alias for Get-Member).
In your case you could type get-netadapter -name "WI-FI" | gm. This returns to you the name, the methods, and properties of the returning object.
To output all properties with values: get-netadapter "WI-FI" | Format-List *

Using Powershell to drive advanced search in Windows Explorer - How to pipe Out-GridView to Windows Explorer?

I have a folder on a remote computer containing security camera video footage. I want to only search the *.mp4 files for those that are created between 2300 and 0600. The code:
$root = "F:\ispy\video\SWVL"
(Get-ChildItem -Path $root) | Where-Object {$_.lastWriteTime.TimeOfDay.Hours -gt 23 -or $_.LastWriteTime.TimeOfDay.Hours -lt 06} | ls | Out-GridView -PassThru
Does this perfectly, and passes the output (file list) to a PowerShell gridview.... BUT, I need the out to show the files in Windows Explorer.
I'm essentially trying to use a PowerShell script as an advanced search filter.
Hoping someone has some ideas. Eventually, I'm planning to use this as a flow -somehow- in power automate and power apps.... but need to crack this first part.
Thanks,
Gregg
AZ
Your use case is not valid. Windows Explorer
You can, in your script, do something like this.. (dropping the call to Out-GridView as it's not needed for your end results)
# find those files
Get-ChildItem -Path 'F:\ispy\video\SWVL' |
Where-Object {
$PSItem.lastWriteTime.TimeOfDay.Hours -gt 23 -or
$PSItem.LastWriteTime.TimeOfDay.Hours -lt 06} |
# copy them to a temp location
Copy-Item -Destination 'SomeTempPath' -Verbose
# open explorer in that location
Invoke-Item -Path 'SomeTempPath'
... then delete that location when you are done.
Windows Explorer-specific search/filtering is only possible in Windows Explorer. So, that means you can only search to get a specific property, then use GUI automation to send that to the Windows Explorer search box.
Otherwise, just skip the script and know this to avoid overcomplicating what you are after.
In Windows Explorer, you can filter the files by date in File Explorer using the date: keyword. You can use this keyword to find files created before, on or after a certain date. You can use the “>” and “<” signs to find files created after or before the given date. “>=” and “<=” also apply here. While you can manually type the date, File Explorer provides a simple calendar that will show up every time you type date: on the search box.
In a script, you'd have to duplicate the aforementioned. Thus capturing the date in your search, opening Windows Explorer and using SendKeys or AutoIT to select the search box and paste the info then sending enter.
Update as per my comment regarding the pop-up calendar. You can do this, in Windows Explorer to filter by date/date ranges
Manually type it in manually, which of course you could GUI automate via SendKeys or AutoIT.
Click the down arrow on any date column.
In the built-in Windows Sandbox on the latest WinOS builds, the popup still works from the Windows Explorer searchbox.
... but not on other host systems.
Update as per our last comments ...
Yet, if you are really trying to send to the Explore serachbox, then this kludge can do it,...
Start-Process -FilePath 'Explorer' 'd:\temp'
Add-Type -AssemblyName System.Windows.Forms
Start-Sleep -Seconds 2
[System.Windows.Forms.SendKeys]::SendWait('+{TAB}'*2)
[System.Windows.Forms.SendKeys]::SendWait('date: 04-Apr-20..11-Jan-21')
Start-Sleep -Seconds 1
[System.Windows.Forms.SendKeys]::SendWait('{Enter}')
... but warning SendKeys is quirky, timing-wise, etc. Sometimes is works, sometimes it does not.

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()

full path of the process running on a windows

Is there any command in windows which can give full path of the process running
tasklist does not give full paths. I do not want to use task manager
The tlist tool is not distributed with the Windows Resource Kit anymore (it's been superseded by tasklist), but is able to list the full path of each process.
You can fetch a copy from the download center.
Now can do it using powershell:
PS C:\> gwmi win32_process | select CommandLine | select-string -pattern "process-name"

Resources