{"id":6672,"date":"2019-04-19T10:24:05","date_gmt":"2019-04-19T14:24:05","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=6672"},"modified":"2019-04-20T09:53:13","modified_gmt":"2019-04-20T13:53:13","slug":"going-down-the-right-path-with-powershell","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/","title":{"rendered":"Going Down the Right %PATH% with PowerShell"},"content":{"rendered":"<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px 5px 5px 0px; float: left; display: inline; background-image: none;\" title=\"foliage-path-small\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg\" alt=\"foliage-path-small\" width=\"300\" height=\"201\" align=\"left\" border=\"0\" \/><\/a>I trust that most of you are aware that the reason it is often easy to run command and programs in Windows, especially items from the command prompt, is thanks to a system environment variable called PATH. When you tell Windows to run a command, without using the complete path to the program, Windows looks in the locations specified by the %PATH% variable. Depending on an application that you install, it might update the %PATH% variable. Although those changes may not take effect until your next reboot or command session. You've probably seen messages to that effect. However, when you uninstall an application, it may not clean up and remove entries to %PATH%.\u00a0 This means you will have values that probably don't exist in %PATH%.<\/p>\n<p>From a technical perspective, I don't think there's any harm or penalty. But if you are like me you like to keep things neat and tidy. Plus this provides an opportunity to teach a few PowerShell concepts and techniques. Let's see how to use PowerShell to manage the %PATH% environment variable.<\/p>\n<p><!--more--><\/p>\n<h2>Displaying the Path<\/h2>\n<p>The first thing to do is to view the current value of %PATH%. This is an environment variable so you can use the ENV: PSDrive. The easy way to reference items is like $env:Path or $env:Computername.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-7.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"My current %PATH%\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-7.png\" alt=\"My current %PATH%\" width=\"1028\" height=\"196\" border=\"0\" \/><\/a><\/p>\n<p>That's a lot to take in. This is one long string of directories separated by a semi-colon, which means you can split the string into an array.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">$env:path -split \";\"\n<\/pre>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-8.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Splitting the %PATH% value\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-8.png\" alt=\"Splitting the %PATH% value\" width=\"874\" height=\"772\" border=\"0\" \/><\/a><\/p>\n<p>Another option would be to use an expression like this to invoke the Split() method on a String object.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">($env:path).split(\";\")\n<\/pre>\n<p>The end result is the same in either case, an array of locations.<\/p>\n<h2>Validating Path Locations<\/h2>\n<p>I already know how to use the <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113418\" target=\"_blank\" rel=\"noopener noreferrer\">Test-Path<\/a> cmdlet. To find locations that no longer exist I need to test each one.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">$env:path -split \";\" | Where-Object {-not (Test-Path $_) }\n<\/pre>\n<p>This expression says \"Take every path from the array and filter where Test-Path returns $False.\" Remember that the -Not operator turns Boolean values on their head. So if Test-Path gives me $False, the -Not operator turns it into $True which means <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113423\" target=\"_blank\" rel=\"noopener noreferrer\">Where-Object<\/a> keeps it in the pipeline.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-9.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Missing %PATH% Locations\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-9.png\" alt=\"Missing %PATH% Locations\" width=\"1028\" height=\"215\" border=\"0\" \/><\/a><\/p>\n<p>These locations no longer exist on my computer, even though they are listed in %PATH%.\u00a0 Again, this doesn't hurt anything as far as I know, but I like to keep things neat.<\/p>\n<h2>Working Cross-Platform<\/h2>\n<p>Windows machines should have $env:Path defined. But if not, you can also use the .NET Framework directly to achieve the same results.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">[System.Environment]::GetEnvironmentVariable(\"PATH\") -split \";\" | Where-Object {-not (Test-Path $_) }\n<\/pre>\n<p>On Linux, and I'm assuming MacOS although I don't have anything the test, you should also have a %PATH% variable. Although be careful because PATH is case sensitive.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-10.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"%PATH% on Linux\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-10.png\" alt=\"%PATH% on Linux\" width=\"1028\" height=\"445\" border=\"0\" \/><\/a><\/p>\n<p>Although if you notice there is a different separator. But no worries. If you are writing some code to run cross-platform, .NET includes a helpful class that tells you what character to use as the splitter or separator.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">$splitter = [System.IO.Path]::PathSeparator\n[System.Environment]::GetEnvironmentVariable(\"PATH\") -split $splitter | Where-Object {-not (Test-Path $_) }\n<\/pre>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-11.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Splitting and Testing in Linux\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-11.png\" alt=\"Splitting and Testing in Linux\" width=\"1028\" height=\"226\" border=\"0\" \/><\/a><\/p>\n<h2>Thinking Objects<\/h2>\n<p>Another approach I'd like you to consider, especially as you think about creating a reusable tool,\u00a0 is to think about writing an object to the pipeline. Here's a prototype function.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Function Test-PathEnv {\n[cmdletbinding()]\nParam()\n\n$splitter = [System.IO.Path]::PathSeparator\n\n$pathenv = [System.Environment]::GetEnvironmentVariable(\"PATH\")\nif ($pathenv) {\n    $env:PATH -split $splitter | Foreach-Object {\n    # create a custom object based on each path\n    [pscustomobject]@{\n        Computername = [System.Environment]::MachineName\n        Path   = $_\n        Exists = Test-Path $_\n    }\n} \n}\nelse {\n    Write-Warning \"Failed to find an environmental path\"\n}\n}\n<\/pre>\n<p>Normally I'd steer away from calling .NET directly but because I want this to work cross-platform, I need to use these classes. The ENV: drive on a Linux box isn't the same on Windows.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-12.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Testing paths on Windows\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-12.png\" alt=\"Testing paths on Windows\" width=\"1024\" height=\"235\" border=\"0\" \/><\/a><\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-13.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Testing paths on Linux\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-13.png\" alt=\"Testing paths on Linux\" width=\"1028\" height=\"329\" border=\"0\" \/><\/a><\/p>\n<h2>Clean Up<\/h2>\n<p>I suppose I shouldn't leave you without mentioning how to clean up problems. I'm going to leave non-Windows remediation to you because it might vary depending on the platform. In Windows, your %PATH% is actually composed of user-specific settings which are stored in the registry under HKCU:\\Environment<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-14.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"User specific PATH settings\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-14.png\" alt=\"User specific PATH settings\" width=\"1028\" height=\"82\" border=\"0\" \/><\/a><\/p>\n<p>And system values found under HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-15.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"System %PATH% values\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-15.png\" alt=\"System %PATH% values\" width=\"1028\" height=\"151\" border=\"0\" \/><\/a><\/p>\n<p>The safe way to clean up would be to use the Windows 10 Control panel and manually edit these settings. But PowerShell has tools to modify the registry so why not? What could possibly go wrong?<\/p>\n<p>[<strong>This is where I make the standard disclaimer that modifying the registry is a potentially risky task and that you take full responsibility and have backup or recovery plans in place<\/strong>.]<\/p>\n<p>I'm going to use my function to get the missing locations and also create backup copies of the registry locations.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">$missing = Test-PathEnv | Where-object {-not $_.exists}\n$savedUser = (Get-itemproperty -path HKCU:\\Environment\\).path\n$savedSystem = (Get-ItemProperty 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment').path\n<\/pre>\n<p>I don't know if the missing path is a user or system value so I need to check both. I can split each saved value into an array and use the -Contains operator to verify.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">foreach ($p in $missing.path) {\n    Write-Host \"Searching for $p\" -ForegroundColor Yellow\n    $user = (Get-itemproperty -path 'HKCU:\\Environment\\').path -split \";\"\n    if ($user -contains $p) {\n        Write-Host \"Found in HKCU\" -ForegroundColor green\n         #insert clean up code\n\n    }\n    $system = (Get-ItemProperty -path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment').path -split \";\"\n    if ($system -contains $p) {\n        Write-Host \"Found in HKLM\" -ForegroundColor Green\n        #insert clean up code\n    }\n}\n<\/pre>\n<p>I'm slowly building a code solution. My plan is to rebuild the appropriate path array without the missing locations and then turn it back into a string which I can use to update the registry property.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">foreach ($p in $missing.path) {\n    Write-Host \"Searching for $p\" -ForegroundColor Yellow\n    $user = (Get-itemproperty -path 'HKCU:\\Environment\\').path -split \";\"\n    if ($user -contains $p) {\n        Write-Host \"Found in HKCU\" -ForegroundColor green\n        $fix = $user | Where-Object {$_ -ne $p}\n        $value = $fix -join \";\"\n        Set-ItemProperty -Path 'HKCU:\\Environment\\' -Name Path -Value $value -WhatIf\n\n    }\n    $system = (Get-ItemProperty -path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment').path -split \";\"\n    if ($system -contains $p) {\n        Write-Host \"Found in HKLM\" -ForegroundColor Green\n        $fix = $system | Where-Object {$_ -ne $p}\n        $value = $fix -join \";\"\n        Set-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment' -Name Path -Value $value -WhatIf\n    }\n}\n<\/pre>\n<p>This is definitely code that you'd want to include support for -WhatIf.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-16.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Cleaning up the registry\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-16.png\" alt=\"Cleaning up the registry\" width=\"1028\" height=\"144\" border=\"0\" \/><\/a><\/p>\n<p>I'm going to live on the edge and run this for real.\u00a0 Because my paths were user specific I won't see the change until I log off and on again. Now I have a clean %PATH% variable.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image-17.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Validating the new %PATH% settings\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/image_thumb-17.png\" alt=\"Validating the new %PATH% settings\" width=\"987\" height=\"772\" border=\"0\" \/><\/a><\/p>\n<h2>Wrap-Up<\/h2>\n<p>As with many of my articles, you may not necessarily need to address this specific task. But hopefully, you learned something new about PowerShell that might help in other ways. I will leave it to you to create a cleanup function.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I trust that most of you are aware that the reason it is often easy to run command and programs in Windows, especially items from the command prompt, is thanks to a system environment variable called PATH. When you tell Windows to run a command, without using the complete path to the program, Windows looks&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"New on the blog: Going Down the Right %PATH% with PowerShell","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[604,534,560,540],"class_list":["post-6672","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-environment","tag-powershell","tag-registry","tag-scripting"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Going Down the Right %PATH% with PowerShell &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"Discover how to validate %PATH% locations with PowerShell and how you might remediate bad values by updating the Windows registry.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Going Down the Right %PATH% with PowerShell &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"Discover how to validate %PATH% locations with PowerShell and how you might remediate bad values by updating the Windows registry.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-19T14:24:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-04-20T13:53:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Going Down the Right %PATH% with PowerShell\",\"datePublished\":\"2019-04-19T14:24:05+00:00\",\"dateModified\":\"2019-04-20T13:53:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/\"},\"wordCount\":875,\"commentCount\":12,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/foliage-path-small_thumb.jpg\",\"keywords\":[\"environment\",\"PowerShell\",\"Registry\",\"Scripting\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/\",\"name\":\"Going Down the Right %PATH% with PowerShell &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/foliage-path-small_thumb.jpg\",\"datePublished\":\"2019-04-19T14:24:05+00:00\",\"dateModified\":\"2019-04-20T13:53:13+00:00\",\"description\":\"Discover how to validate %PATH% locations with PowerShell and how you might remediate bad values by updating the Windows registry.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/foliage-path-small_thumb.jpg\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/foliage-path-small_thumb.jpg\",\"width\":300,\"height\":201},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6672\\\/going-down-the-right-path-with-powershell\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Going Down the Right %PATH% with PowerShell\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Going Down the Right %PATH% with PowerShell &#8226; The Lonely Administrator","description":"Discover how to validate %PATH% locations with PowerShell and how you might remediate bad values by updating the Windows registry.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/","og_locale":"en_US","og_type":"article","og_title":"Going Down the Right %PATH% with PowerShell &#8226; The Lonely Administrator","og_description":"Discover how to validate %PATH% locations with PowerShell and how you might remediate bad values by updating the Windows registry.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/","og_site_name":"The Lonely Administrator","article_published_time":"2019-04-19T14:24:05+00:00","article_modified_time":"2019-04-20T13:53:13+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Going Down the Right %PATH% with PowerShell","datePublished":"2019-04-19T14:24:05+00:00","dateModified":"2019-04-20T13:53:13+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/"},"wordCount":875,"commentCount":12,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg","keywords":["environment","PowerShell","Registry","Scripting"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/","name":"Going Down the Right %PATH% with PowerShell &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg","datePublished":"2019-04-19T14:24:05+00:00","dateModified":"2019-04-20T13:53:13+00:00","description":"Discover how to validate %PATH% locations with PowerShell and how you might remediate bad values by updating the Windows registry.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/04\/foliage-path-small_thumb.jpg","width":300,"height":201},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6672\/going-down-the-right-path-with-powershell\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Going Down the Right %PATH% with PowerShell"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":7604,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7604\/discovering-provider-specific-commands\/","url_meta":{"origin":6672,"position":0},"title":"Discovering Provider Specific Commands","author":"Jeffery Hicks","date":"July 22, 2020","format":false,"excerpt":"I've been diving into PowerShell help lately while preparing my next Pluralsight course. One of the sad things I have discovered is the loss of provider-aware help. As you may know, some commands have parameters that only exist when using a specific PSDrive.\u00a0 For example, the -File parameter for Get-ChildItem\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/07\/gsyn-2.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":4305,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4305\/what-powershell-script-was-i-working-on\/","url_meta":{"origin":6672,"position":1},"title":"What PowerShell Script Was I Working On?","author":"Jeffery Hicks","date":"March 24, 2015","format":false,"excerpt":"Last week I shared a script for finding recently modified files in a given directory. In fact, it wouldn't be that difficult to find the last files I was working on and open them in the PowerShell ISE. Assuming my Get-RecentFile function is loaded it is a simple as this:\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":49,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/49\/reading-the-registry-in-powershell\/","url_meta":{"origin":6672,"position":2},"title":"Reading the Registry in PowerShell","author":"Jeffery Hicks","date":"August 26, 2006","format":false,"excerpt":"One of the great PowerShell features is that it treats the registry like any other location or directory. In PowerShell you can connect directly to the registry and navigate the key hierarchy just as if it as a logical drive with folders. I have a very brief demonstration script you\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1653,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/1653\/the-powershell-day-care-building-scriptblocks\/","url_meta":{"origin":6672,"position":3},"title":"The PowerShell Day Care: Building ScriptBlocks","author":"Jeffery Hicks","date":"September 22, 2011","format":false,"excerpt":"Good morning kids and welcome to the PowerShell Day Care center. We offer a creative and nurturing environment for PowerShell professionals of all ages. Later there might even be juice and cookies. But first let's get out our blocks, our scriptblocks, and start building. I've written a number of posts\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4489,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4489\/teeing-up-to-the-clipboard\/","url_meta":{"origin":6672,"position":4},"title":"Teeing Up to the Clipboard","author":"Jeffery Hicks","date":"August 12, 2015","format":false,"excerpt":"Because I spend a great part of my day creating PowerShell related content, I often need to copy command output from a PowerShell session. The quick and dirty solution is to pipe my expression to the Clip.exe command line utility. get-service | where { $_.status -eq 'running'} | clip This\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3613,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/3613\/updated-powershell-script-profiler\/","url_meta":{"origin":6672,"position":5},"title":"Updated PowerShell  Script Profiler","author":"Jeffery Hicks","date":"January 15, 2014","format":false,"excerpt":"Last year I wrote a sidebar for the Scripting Guy, Ed Wilson and an update to his PowerShell Best Practices book. I wrote a script using the new parser in PowerShell 3.0 to that would analyze a script and prepare a report showing what commands it would run, necessary parameters,\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"script-profile-report","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2014\/01\/script-profile-report.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2014\/01\/script-profile-report.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2014\/01\/script-profile-report.png?resize=525%2C300 1.5x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/6672","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=6672"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/6672\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=6672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=6672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=6672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}