I've been chipping in on a forum post about finding if a given file exists in any folder within the system environmental %PATH% variable using Windows PowerShell. There are several ways you might approach this. But the best way in my opinion is to leverage the PowerShell pipeline. Perhaps you don't really need the solution but I think it is a valuable learning opportunity.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
First off, you can access Windows environmental variables with the Environment PSProvider. All environmental variables can be in the ENV: psdrive.
[cc lang="PowerShell"]
PS S:\> dir env:
[/cc]
The easy way to reference a specific variable is like this:
[cc lang="PowerShell"]
PS S:\> $env:PSModulePath
C:\Users\Jeff\Documents\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules\;C:\Program Files\Intel Corporation\PowerShell\Modules
[/cc]
So to get the %PATH% variable we would use $env:Path. Because the path is stored as a semi-colon delimted entries we can split it.
[cc lang="PowerShell"]
PS S:\> $env:path.split(";")
%SystemRoot%\system32\WindowsPowerShell\v1.0\
C:\Program Files\Common Files\Microsoft Shared\Microsoft Online Services
C:\Program Files (x86)\Common Files\Microsoft Shared\Microsoft Online Services
C:\Program Files (x86)\VMware\VMware vSphere CLI\Perl\site\bin
C:\Program Files (x86)\VMware\VMware vSphere CLI\Perl\bin
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common
C:\Windows\system32
C:\Windows
C:\Windows\System32\Wbem
C:\Windows\System32\WindowsPowerShell\v1.0\
c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\
c:\Program Files\Microsoft SQL Server\100\Tools\Binn\
c:\Program Files\Microsoft SQL Server\100\DTS\Binn\
c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\
c:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\
C:\Windows\System32\Windows System Resource Manager\bin
C:\Program Files\Windows Imaging\
C:\Windows\System32\Windows System Resource Manager\bin
[/cc]
Each path is written to the pipeline. Because the goal is to filter paths that only contain the file, we can take advantage of Where-Object.
[cc lang="PowerShell"]
PS S:\> $env:path.split(";") | Where {test-path -path "$_\notepad.exe"}
C:\Windows\system32
C:\Windows
[/cc]
The $_ is the current object in the pipeline, or each path element that comes from splitting the path. If Test-Path is True, then the path element is passed to the end of the pipeline. An alternative might be to pipe to Join-Path which uses the piped in value for its -Path parameter.
[cc lang="PowerShell"]
PS S:\> $env:path.split(";") | Join-path -child "notepad.exe" | Where {test-path $_}
C:\Windows\system32\notepad.exe
C:\Windows\notepad.exe
[/cc]
If we wanted to get the file details we can take this a step further and pipe to Get-Item. Again, the value will be used for the -Path parameter.
[cc lang="PowerShell"]
PS S:\> $env:path.split(";") | Join-path -child "notepad.exe" | Where {test-path $_} | get-item
Directory: C:\Windows\system32
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 7/13/2009 9:39 PM 193536 notepad.exe
Directory: C:\Windows
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 7/13/2009 9:39 PM 193536 notepad.exe
[/cc]
For this particular exercise there is one limitation: any path element that uses a environmental variable like %Windir%, won't work. I'll work on that separately. The main takeaway is to look at cmdlet parameters and see where you can leverage the pipeline. Let PowerShell do the work for you.