Use Powershell to delete file from a folder set by windows registry value - powershell

Sorry if this has been answered before, I have tirelessly searched and cannot find the exact answer I am a Mac user and have not ventured into Windows registry before.
I am creating an installer for audio plugins and have a separate demo version of the titles. In the registry for the demo version, I have the entry
Demo=1
and also have paths set for various components of the plugins, which are optionally installed, these are stored in the registry as the user may install these into different directories depending on their host software
VST3=C:\Somepath\VST3
VST32=C\AnotherPath\VSTPlugins
VST64=C\AnotherPathAgain\VSTPlugins
I have found how to search the registry to check if Demo=1
$val = Get-ItemProperty -Path hklm:software\Audio Vitamins\Structure -Name “Demo”
if($val.Demo -eq 1)
{
**** This is where I need help *****
}
How do I set Powershell to remove a particular file 'structure.vst3' from the path set in VST3 or or 'structure.dll' from the paths set in VST32 and VST64. Note these can all be present or only 1 of them depending on the original install.

You have a couple of different paths (pun intended) you can take here.
You can organize your "demo = 1" files into one folder and the others in another and reference the demo folder location in the registry. Then you get the file location and use del to remove them. Much easier and doesn't require you to track which ones are there with unnecessary registry entries.
$demofolder = gp -path HKLM:\path\to\registry\key -Name "demofolder"
dir $demofolder -file|%{del $_ -force}

Related

Running powershell without useriteraction

start "odopen://sync/?siteId=$siteid17&webId=$webid17&listId=$listid17&userEmail=$upn&webUrl=$URL17&webtitle=$webtitle17&listtitle=$listtitle17"
How is it possible to run the following command inside Powershell without an appearing popup window or any userinteraction? I've tried adding /ArgumentList "/S", "/Background". Also tried with -WindowStyle Hidden at the end. Appreciate some help :)
Your command as-is basically says "Start the program that opens odopen:// (OneDrive) links" and can't really be given any silent style instructions. The proper way to configure this kind of thing is through OneDrive Group Policies, but we can cheat and set registry keys.
The link above goes into detail about how to configure group policy, but also tells us that the specific group policy setting to "Configure team site libraries to sync automatically" sets this registry key:
[HKCU\Software\Policies\Microsoft\OneDrive\TenantAutoMount]"LibraryName"="LibraryID"
And that your LibraryID is in this format, which looks familiar:
tenantId=xxx&siteId=xxx&webId=xxx&listId=xxx&webUrl=httpsxxx&version=1
So to put it in a script, I would use something like this, adapted from Nicola Suter's blog post here:
$tenantAutoMountRegKey = "HKLM:\SOFTWARE\Policies\Microsoft\OneDrive\TenantAutoMount"
$autoMountTeamSitesList= #{
#Enter your SharePoint libraries to configure here as key/value pairs
MySharePoint="odopen://sync/?siteId=$siteid17&webId=$webid17&listId=$listid17&userEmail=$upn&webUrl=$URL17&webtitle=$webtitle17&listtitle=$listtitle17"
}
# Check if the key exists and create if missing:
if (-not (Test-Path $tenantAutoMountRegKey)){ New-Item -Path $tenantAutoMountRegKey -Force }
# Add the sites for automatic mounting
$autoMountTeamSitesList | Set-ItemProperty -Path $tenantAutoMountRegKey -Name $_.Key -Value $_.Value
This generally takes effect the next time a user signs into OneDrive, though Microsoft warns it may take up to 8 hours to start syncing (Keeps hundreds of users from syncing the same library at the same time)
TL;DR: You cannot.
Using odopen will always show sign-in window (as stated here: https://learn.microsoft.com/en-us/onedrive/deploy-on-windows#help-users-sign-in), what you can do is only populate it with data, which is what you are already doing.
If you want to do it silently, there is documentation about it: https://learn.microsoft.com/en-us/onedrive/use-silent-account-configuration

Enforce "List" view on all Windows Explorer views (including all Media folders)

I almost never use the "Details" View in Windows File Explorer as I mostly just want to see as many files and folder names on the page as I can, ("Type" or "File Modified" reduce the amount of files that I can see), so I want to default all my new systems to "List" view in all File Explorer windows (I do care about the above information, but much less frequently, so can change as required or use PowerShell to analyse filesystem details). So I want "List" view forcibly enabled everywhere at all times (in system folders, in document folders, in media folders - I don't want "Thumbnail" view for every film in a folder, it's useless information for me 99% of the time!). This is quite awkward to achieve in Windows, as I have to go into a folder of each view type, then set it to "List" view, then "Apply to all folders", but it must be doable by PowerShell I think...
I would like to know how to achieve "List" view in all Windows (including for Media folders etc) via PowerShell / registry so that I can setup the system to my preferences, and equally, this question applies for people that prefer "Details" view everywhere and how they might achieve that?
This question is related to Configure Windows Explorer Folder Options through Powershell but I can't ask it under there as if I did so my question would be deleted as off-topic since he seemed to only be asking about Hidden Files and Extensions, so I have to create a new question. That questions answer is possibly a clue towards enforcing "List" view, but I've not been able to find the right settings yet (the below enables Hidden files and folders and makes file extensions visible, and these are also settings that I find useful and apply to all systems):
$key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
Set-ItemProperty $key Hidden 1
Set-ItemProperty $key HideFileExt 0
Set-ItemProperty $key ShowSuperHidden 1
Stop-Process -processname explorer
For anyone that finds this page, I finally found a comprehensive solution for this from another page, that seems to work perfectly:
# *** Change the value of $Backup to the path of an existing folder
# *** where you want to registry backups saved to.
$backup = "C:\Users\$env:USERNAME\Documents\Backup\Folder View Defaults"
# ----------------------------------------------------------------
# Paths for PowerShell commands use the registry Get-PSDrives, hence the ':'
$src = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes'
$dst = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes'
$TVs = "$dst\*\TopViews\*"
# ----------------------------------------------------------------
# Paths for reg.exe commands do not use a ':'
$bagMRU = 'HKCR\Local Settings\Software\Microsoft\Windows\Shell\BagMRU'
$bags = 'HKCR\Local Settings\Software\Microsoft\Windows\Shell\Bags'
$defaults = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams\Defaults'
# ----------------------------------------------------------------
# Backup & then delete saved views and 'Apply to folders' defaults
reg export $BagMru "$Backup\bagMRU.reg"
reg export $Bags "$Backup\bags.reg"
reg export $Defaults "$Backup\defaults.reg"
reg delete $bagMRU /f
reg delete $bags /f
reg delete $defaults /f
reg delete ($dst.Replace(':','')) /f
#------------------* The Magic is here *--------------------------
# First, we copy HKLM\...\FolderTypes to HKCU\...\FolderTypes
Copy-Item $src "$(Split-Path $dst)" -Recurse
# Set all 'LogicalViewMode' values to the desired style
# Edit "$key2edit.SetValue('LogicalViewMode', 4)" as desired
# Use: 1 = Details, 2 = Tiles, 3 = Icons, 4 = List, 5 = Content
Get-ChildItem $TVs | % {
$key2edit = (get-item $_.PSParentPath).OpenSubKey($_.PSChildName, $True);
$key2edit.SetValue('LogicalViewMode', 4) # <== Set this value to the view required
$key2edit.Close()
}
Get-Process Explorer | Stop-Process

Determining Installed Visual Studio Path for 2017

I have a powershell script that looks at a list of VS installations, and determines the highest version installed. It then uses the InstallDir for that version, and uses it to access various commands.
It still uses the lower versions, however.
As of VS2017, it appears that the Registry keys are no longer saved in the same way. I need to update the script to be able to figure out the 2017 settings.
#Add New Versions to this list when new versions of VS are released
$VsVersionsToDisable = "10.0", "11.0", "12.0", "14.0"
[System.Collections.ArrayList]$VsVersions = $VsVersionsToDisable
#Find the Highest installed VS Version, and use it for the TFS.exe Command.
foreach ($version in $VsVersions | Sort-Object -Descending)
{
$keyPath = "HKCU:\Software\Microsoft\VisualStudio\$version`_Config"
If (Test-Path $keyPath)
{
$aliasPath = Get-ItemProperty -Path $keyPath | Select-Object `
-ExpandProperty InstallDir
$proxyPath = Join-Path $aliasPath "tf.exe"
set-alias proxyTF $proxyPath
}
}
To avoid an XY question: We use this script to configure the TFS Proxy settings for a user. It determines the highest installed version, uses it to find the proxy, then iterates through the lower versions configuring their proxy settings with the same value.
What is the best way to determine the installation directory (and also the tf.exe location) for VS2017?
From what I can see, use the SxS\VS7 option:
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7
It should give you the root paths to Visual Studio:
That should get you going.
The tf.exe location is then stored using a symlink under:
.\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe
Since you're using PowerShell, check out https://github.com/microsoft/vssetup.powershell, which is a PS module for detecting installations of VS2017+.
Otherwise, you could need to rely on the Nuget package which is the supported means of detecting VS.
See also this answer on a related question, which predates the PS module I listed above but contains some unsupported methods for finding VS.
I did use this as a reference and came to a solution in another way.
I'm not sure how resilient it is with regards to other versions, but it did the trick for me. It get's the directory of devenv and then I add the extra on the end for TFS. Obviously if the structure is different, then we are screwed.
Hope it helps.
$regKey = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\devenv.exe"
$visualStudioDir = Get-ItemPropertyValue -Path $regKey -Name "(Default)"
$visualStudioDir = ($visualStudioDir.Replace("devenv.exe","")).replace("`"","")
$tfsPath = 'CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe'
Set-Alias tf $visualStudioDir$tfsPath
tf workspaces

Boxstarter or PowerShell command to change "Opens With" properties

I'm trying to develop my own Boxstarter script for spinning up new machines. I just realized that I'd really like to add a line that will change default applications to open certain file types. For example, I want to open .txt files with Notepad++. I know how to do this by right-click the file and checking it's properties, but is there a line I can add to my Boxstarter script that will do it? Or, since Boxstarter is basically a special set of PowerShell commands, is there a PowerShell command I can invoke directly to change the opens with property? I did some searching, and most of the results were about how to get PowerShell to open something, not change the opens with property. The rest were all about how to open PowerShell.
Another similar, but not quite the same, way to go about this is to change the file association you want to associate with a particular applicaition. Chocolatey includes some helper commands to do this and is therefore available to your Boxstarter package. Here is an excerpt from one of my Boxstarter packages:
Install-ChocolateyFileAssociation ".txt" "$env:programfiles\Sublime Text 2\sublime_text.exe"
Install-ChocolateyFileAssociation ".dll" "$($Boxstarter.programFiles86)\jetbrains\dotpeek\v1.1\Bin\dotpeek32.exe"
So now double clicking on any text file opens sublime or any dll opens dotpeek.
But I agree. Its still helpful to be able to add to the "Open With..." list.
Thanks to #Raf for pointing me in the right direction. Here's the code to change the OpensWith property of .txt files:
$principal = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$acl = $key.GetAccessControl()
$right = "SetValue"
$denyrule = New-Object System.Security.AccessControl.RegistryAccessRule($principal,$right,"DENY")
$ret = $acl.RemoveAccessRule($denyrule)
$ret = $key.SetAccessControl($acl)
Set-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice -Name ProgId -Value Applications\notepad++.exe
Slightly modified from an answer in the TechNet forums.
I haven't figured out if there's a boxstarter shortcut for this, but changing the ACL rules was the key. Without it, you don't have the proper access to change this particular registry item. Even when I tried running Powershell as Admin and made sure I had all the right permissions on the UserChoice key (both the administrator account and my user account had Full Control), I kept getting an error that the Requested registry access is not allowed.

Powershell get latest on a working folder?

I am trying to get latest on a specific folder and was wondering how I would do this. I have been reading the MSDN documentation about the Workspace class but unfortunately it doesn't seem to provide any information about how I would go about getting latest of a specific folder.
For example, I have a single workspace but with multiple working folders. My PowerShell script can get latest but only at workspace level. Is it possible to get it from a working directory level or at a particular folder level?
Thanks in advance, DS.
EDIT
I believe this is possible as power tools is able to do it via right clicking a folder and getting latest. Ideally, want to replicate this.
http://msdn.microsoft.com/en-us/library/Microsoft.TeamFoundation.VersionControl.Client.Workspace.aspx
The below shows my script in practice..
$tfs = .\tfs-get-instance.ps1 -uri $uri
$vcs = $tfs.TfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
[psobject]$workspace = $vcs.GetWorkspace([System.Environment]::MachineName, [System.Environment]::UserName)
$workspace.Map($sourceFolder, $localFolder)
$result = $workspace.GetLocalItemForServerItem($sourceFolder);
if ($result -ne "")
{
echo $result
}
You should be able to use the Workspace.Get Method (String[], VersionSpec, RecursionType, GetOptions) to get what you want.
On the other hand, if you don't necessarily want to do it using the .NET objects, you could let tf.exe do the actual work, like the following:
& $TfExePath workfold /map "$codePath" "$LocalFolderPath" /collection:"$tfCollection" /workspace:$workspaceName
& $TfExePath get "$codePath" /version:$ChangeSet /force /overwrite /all /recursive $workspaceName
On the other hand, if you have the TF PowerTools installed you should also have PowerShell cmdlets for working with TFS. I have never used them, but I'm guessing you should be able to use them instead of using tf.exe if you want to. I would probably go for the PowerShell cmdlets in the power tools if they fill your need.