0

I'm trying to make a PowerShell script to modify the Registry values that set the default application for the .ps1 file extension. Sadly I wasn't able to get very far with the script because the PSDrive didn't have a path for HKEY_CLASSES_ROOT didn't exist.

After finding the solution on the Microsoft website using:

New-PSDrive -PSProvider registry -Root 'HKEY_CLASSES_ROOT' -Name 'HKCR'

I then thought about including a bit of code to check if this PSDrive path had been set before continuing, and so now it appears at the top of the script as shown below:

#####
IF (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "Requesting administration privileges..."; Start-Sleep -s 2; Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }

Write-Host "Administration privileges have been granted."
Start-Sleep -s 2
#####

Write-Host "Checking if 'HKEY_CLASSES_ROOT' path has been set...`n"

If (Get-PSDrive | Where{$_.Name -CMatch 'HKCR' -and $_.Root -CMatch 'HKEY_CLASSES_ROOT'}) {
    Write-Output "Path has already been set"
} Else {
    Write-Output "Path has not been set. Setting path now..."
    New-PSDrive -PSProvider registry -Root 'HKEY_CLASSES_ROOT' -Name 'HKCR' >$Null 2>&1
}

Write-Host "`nDone"
Start-Sleep -s 2

Write-Host "Setting .PS1 (PowerShell scripts extension) file association with VS Code... " -NoNewLine
Set-ItemProperty -Path "HKCR:\Microsoft.PowerShellScript.1\Shell\Open\Command" -Name "(Default)" -Value {C:\Program Files\Microsoft VS Code\Code.exe "%1"}
Start-Sleep -s 2
Write-Host "Done"
Exit

Unfortunately I can't get the below IF statement to work:

If (Get-PSDrive | Where{$_.Name -CMatch 'HKCR' -and $_.Root -CMatch 'HKEY_CLASSES_ROOT'}) {
    Write-Output "Path has already been set"
} Else {
    Write-Output "Path has not been set. Setting path now..."
    New-PSDrive -PSProvider registry -Root 'HKEY_CLASSES_ROOT' -Name 'HKCR' >$Null 2>&1
}

Whilst running the command I'm always presented with the following message (the 'Else' statement) and each time I re-run the script I never see the 'If' statement:

Path has not been set. Setting path now...

UPDATE 1

The one line code on line 2 is to elevate the PowerShell script with administrator privileges. Lines 3 and 4 are you let the user know that the script has been elevated.

I tried your code nut with Write-Output rather than verbose and I'm still unable to see the response matched with the 'If' statement.

Write-Host "Checking if 'HKEY_CLASSES_ROOT' path has been set...`n"

If (Get-PSDrive | 
    Where {
            ($PSitem.Name -Match 'HKCR') -and 
            ($PSitem.Root -Match 'HKEY_CLASSES_ROOT')
          }
   )
{Write-Output "Path has already been set"}
Else
{
    Write-Output "Path has not been set. Setting path now..."
    New-PSDrive -PSProvider registry -Root "HKEY_CLASSES_ROOT" -Name "HKCR" >$Null 2>&1
}

However, if I set the PSDrive manually with:

New-PSDrive -PSProvider registry -Root "HKEY_CLASSES_ROOT" -Name "HKCR" >$Null 2>&1

and then check it exists with:

PS D:\Users\Will> Get-PSDrive | Where{$_.Name -Match 'HKCR' -and $_.Root -Match 'HKEY_CLASSES_ROOT'}

Name           Used (GB)     Free (GB) Provider      Root                                               CurrentLocation
----           ---------     --------- --------      ----                                               ---------------
HKCR                                   Registry      HKEY_CLASSES_ROOT

This works perfectly fine. I would just like my script to check this and if the PSDrive hasn't been set, then set it.

willowen100
  • 29
  • 1
  • 1
  • 4
  • 4
    “*Can’t get it to work*” doesn’t help us help you. What does or doesn’t happen? Have you tried breaking the commands apart and checking that each do what you expect? – Doug Maurer Jan 04 '21 at 01:31
  • Ditto to what Doug Mauer said, and also, why is that [elevation] if statement all on one line? That would be fine in an interactive console session, though it has no benefit in a script. In a script, stuff like this makes this hard to read, hard to troubleshoot, etc... Yet, all have their own styles. Remember, Windows is not case sensitive, so, CMatch is really moot for what you seem to be after? – postanote Jan 04 '21 at 08:21

1 Answers1

0

Try these refactored sections.

If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::
   GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator'
    )
) 
{ 
    Write-Host 'Requesting administration privileges...'
    Start-Sleep -s 2
    Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
}


If (Get-PSDrive | 
    Where {
            ($PSitem.Name -eq 'HKCU') -and 
            ($PSitem.Root -eq 'HKEY_CURRENT_USER')
          }
   )
{Write-Verbose -Message 'Specified PSDrive valid' -Verbose}
Else
{
    Write-Warning -Message 'PSDrive not specific for the registry key specified.'e
}
# Results
<#
VERBOSE: Specified PSDrive valid
#>


If (Get-PSDrive | 
    Where {
            ($PSitem.Name -Match 'HKCR') -and 
            ($PSitem.Root -Match 'HKEY_CLASSES_ROOT')
          }
   )
{Write-Verbose -Message 'Specified PSDrive valid'}
Else
{
    Write-Warning -Message 'PSDrive not specific for the registry key specified.'
}
# Results
<#
WARNING: PSDrive not specific for the registry key specified.
#>
postanote
  • 15,138
  • 2
  • 14
  • 25