Boxstarter or PowerShell command to change "Opens With" properties - powershell

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.

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

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

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}

Powershell to find machine that created a file

I have a script that monitors the filesystem using FileWatcher.IO in Powershell.
Currently it finds the user that made the file with:
$owner = (Get-Acl $path).Owner
And it finds the computer that the file was made on with:
$Computer = get-content env:computername
But I'd also like to obtain what machine the file was created from. For instance, if a user is logged into a terminal server, I can see the file is made on the terminal server. But I want to know the host name of the local machine that made the file on the terminal server.
Is this possible? I've been searching the msdn PSEventArgs Class page without much success.
That information is not going to be stored in the file or its metadata, so no there's no straightforward way to get at it.
By the way, you can just use $env:computername directly as a variable; there's no need to use Get-Content.

Accessing Excel VBA editor from Powershell

I want to execute the Project Properties command in the VBA menu of Excel application using Powershell.
Following is the script -
$excelApplication = New-Object -ComObject ("Excel.Application")
$excelApplication.Visible = $True
$workbook = $excelApplication.Workbooks.Open("C:\Workbooks\PasswordProtectedVBEFile.xlsm")
$appReference = $workbook.Application
$appReference.VBE.CommandBars(1).FindControl(2578, $True).Execute()
I encounter the error - You cannot call a method on a null-valued expression., an inspection revealed - $appReference.VBE is empty. i.e. Write-Host $appReference.VBE outputs empty line.
I want help in troubleshooting why do I get an empty value for VBE?
I found the way out!
In short, we need to grant access to VBA Project Model explicitly before we could automate/access programmatically using script.
Journey to this discovery was interesting. I stumbled on this git project which helped me troubleshoot the problem.
The solution to my problem was this security check which I found in referred project
$mo = Get-ItemProperty -Path HKCU:Software\Microsoft\Office\*\Excel\Security `
-Name AccessVBOM `
-EA SilentlyContinue | `
? { !($_.AccessVBOM -eq 0) } | `
Measure-Object
This security check ensures VBA Project model is available programmatically. Well though this is just a check against registry, I wanted to know how to set a value. It was simple and one time activity in Excel.
You could allow such programmatic access by checking the check box "Trust access to the VBA Project model". This setting could be accessed by navigating in Excel (2010) File > Options > Trust Center > Trust Center Settings > Macro Settings.

creating a shortcut on a remote desktop, but the shortcut is created with a "file" instead of "file folder" as the "target type"

I'm trying to create a shortcut on a remote desktop in the domain here, and I'm a domain admin. If I run the following code directly on the target machine, the shortcut can be created and is able to lead me to the target path.
$shortcutpath3 = "c:\Users\Public\Desktop\Shortcuts to Test Custom\VV 1211 -TC.lnk"
$WshShell3 = New-Object -comObject WScript.Shell
$Shortcut3 = $WshShell3.CreateShortcut($shortcutpath3)
$Shortcut3.TargetPath = "\\machine\testcustom\"
$Shortcut3.Save()
I saved this script as test.ps1, run it with folloing code on a different mahchine. The code ends without any errors/warings, and the shortcut is created on the target machine with the propeties i specified. But it cannot lead me to the target place, it actually ask me to pick a program to open that file. I compared the properties of the 2 shortcuts, and found that the "target type" of the broken shortcut is "file" while it is "file folder" for a good shortcut.
Invoke-Command -ComputerName TARGETSERVER -FilePath test.ps1
Any idea how i can fix this? And why is this happening? Thank!!!
I had the same problem and and I used Get-Item to make it work. Try this:
$targetPath = Get-Item("\\machine\testcustom\")
$WshShell3 = New-Object -comObject WScript.Shell
$Shortcut3 = $WshShell3.CreateShortcut($shortcutpath3)
$Shortcut3.TargetPath = $targetPath.FullName
$Shortcut3.Save()
Since you're a domain admin I'd strongly recommend doing this with a Group Policy Preference. You can restrict shortcut creation to particular users/groups/computers/etc. via item-level targeting.
I've been battling this for the past several hours, Googling to no avail. For posterity, here's my summary. While alternatives suggestions are appreciated:
PowerShell inexplicably has no direct way to create a shortcut. It can create symbolic link, but 1) it requires admin rights, and 2) it behaves differently.
Group Policy Preferences are great--but only if your machines are in office or routinely on a VPN.
If you're trying to create a shortcut to a network folder, setting the TargetPath to that folder only works if the computer actually can reach it when the script runs, i.e. same issue as with Group Policy Preferences. PowerShell will create the shortcut, but the Target Type will be a File rather than a File Folder (and I found no info online how to control that; trailing slash or not doesn't matter).
The behavior of running these code suggestions varies depending whether you run this interactively or as a script.
Here's what I found does work:
Set the $shortcut.TargetPath to "C:\Windows\Explorer.exe"
Add a line: $shortcut.Arguments = """Target folder""" (the """ are needed as an escape character for the shortcut to show as C:\Windows\Explorer.exe "Target folder")
So for your example above, the following should work (assuming permissions to c:\Users\Public\Desktop):
$shortcutpath3 = "c:\Users\Public\Desktop\Shortcuts to Test Custom\VV 1211 -TC.lnk"
$WshShell3 = New-Object -comObject WScript.Shell
$Shortcut3 = $WshShell3.CreateShortcut($shortcutpath3)
$Shortcut3.TargetPath = "C:\Windows\Explorer.exe"
$shortcut.Arguments = """\\machine\testcustom\"""
$Shortcut3.Save()