-
-
Save YoraiLevi/0f333d520f502fdb1244cdf0524db6d2 to your computer and use it in GitHub Desktop.
<# | |
.SYNOPSIS | |
Requires powershell 5 or later | |
Provides Get and Set functions for KnownFolders | |
.EXAMPLE | |
PS> Set-KnownFolderPath Desktop $ENV:USERPROFILE/Desktop | |
.EXAMPLE | |
PS> $Path="" | |
PS> Get-KnownFolderPath Desktop ([ref]$Path) | |
.LINK | |
https://docs.microsoft.com/en-us/windows/win32/shell/known-folders | |
.LINK | |
https://stackoverflow.com/questions/25709398/set-location-of-special-folders-with-powershell | |
.LINK | |
https://gist.github.com/YoraiLevi/0f333d520f502fdb1244cdf0524db6d2 | |
#> | |
# using namespace System.Management.Automation | |
# Define known folder GUIDs | |
$KnownFolders = @{ | |
'3DObjects' = '31C0DD25-9439-4F12-BF41-7FF4EDA38722'; | |
'AddNewPrograms' = 'de61d971-5ebc-4f02-a3a9-6c82895e5c04'; | |
'AdminTools' = '724EF170-A42D-4FEF-9F26-B60E846FBA4F'; | |
'AppUpdates' = 'a305ce99-f527-492b-8b1a-7e76fa98d6e4'; | |
'CDBurning' = '9E52AB10-F80D-49DF-ACB8-4330F5687855'; | |
'ChangeRemovePrograms' = 'df7266ac-9274-4867-8d55-3bd661de872d'; | |
'CommonAdminTools' = 'D0384E7D-BAC3-4797-8F14-CBA229B392B5'; | |
'CommonOEMLinks' = 'C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D'; | |
'CommonPrograms' = '0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8'; | |
'CommonStartMenu' = 'A4115719-D62E-491D-AA7C-E74B8BE3B067'; | |
'CommonStartup' = '82A5EA35-D9CD-47C5-9629-E15D2F714E6E'; | |
'CommonTemplates' = 'B94237E7-57AC-4347-9151-B08C6C32D1F7'; | |
'ComputerFolder' = '0AC0837C-BBF8-452A-850D-79D08E667CA7'; | |
'ConflictFolder' = '4bfefb45-347d-4006-a5be-ac0cb0567192'; | |
'ConnectionsFolder' = '6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD'; | |
'Contacts' = '56784854-C6CB-462b-8169-88E350ACB882'; | |
'ControlPanelFolder' = '82A74AEB-AEB4-465C-A014-D097EE346D63'; | |
'Cookies' = '2B0F765D-C0E9-4171-908E-08A611B84FF6'; | |
'Desktop' = 'B4BFCC3A-DB2C-424C-B029-7FE99A87C641'; | |
'Documents' = 'FDD39AD0-238F-46AF-ADB4-6C85480369C7'; | |
'Downloads' = '374DE290-123F-4565-9164-39C4925E467B'; | |
'Favorites' = '1777F761-68AD-4D8A-87BD-30B759FA33DD'; | |
'Fonts' = 'FD228CB7-AE11-4AE3-864C-16F3910AB8FE'; | |
'Games' = 'CAC52C1A-B53D-4edc-92D7-6B2E8AC19434'; | |
'GameTasks' = '054FAE61-4DD8-4787-80B6-090220C4B700'; | |
'History' = 'D9DC8A3B-B784-432E-A781-5A1130A75963'; | |
'InternetCache' = '352481E8-33BE-4251-BA85-6007CAEDCF9D'; | |
'InternetFolder' = '4D9F7874-4E0C-4904-967B-40B0D20C3E4B'; | |
'Links' = 'bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968'; | |
'LocalAppData' = 'F1B32785-6FBA-4FCF-9D55-7B8E7F157091'; | |
'LocalAppDataLow' = 'A520A1A4-1780-4FF6-BD18-167343C5AF16'; | |
'LocalizedResourcesDir' = '2A00375E-224C-49DE-B8D1-440DF7EF3DDC'; | |
'Music' = '4BD8D571-6D19-48D3-BE97-422220080E43'; | |
'NetHood' = 'C5ABBF53-E17F-4121-8900-86626FC2C973'; | |
'NetworkFolder' = 'D20BEEC4-5CA8-4905-AE3B-BF251EA09B53'; | |
'OriginalImages' = '2C36C0AA-5812-4b87-BFD0-4CD0DFB19B39'; | |
'PhotoAlbums' = '69D2CF90-FC33-4FB7-9A0C-EBB0F0FCB43C'; | |
'Pictures' = '33E28130-4E1E-4676-835A-98395C3BC3BB'; | |
'Playlists' = 'DE92C1C7-837F-4F69-A3BB-86E631204A23'; | |
'PrintersFolder' = '76FC4E2D-D6AD-4519-A663-37BD56068185'; | |
'PrintHood' = '9274BD8D-CFD1-41C3-B35E-B13F55A758F4'; | |
'Profile' = '5E6C858F-0E22-4760-9AFE-EA3317B67173'; | |
'ProgramData' = '62AB5D82-FDC1-4DC3-A9DD-070D1D495D97'; | |
'ProgramFiles' = '905e63b6-c1bf-494e-b29c-65b732d3d21a'; | |
'ProgramFilesX64' = '6D809377-6AF0-444b-8957-A3773F02200E'; | |
'ProgramFilesX86' = '7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E'; | |
'ProgramFilesCommon' = 'F7F1ED05-9F6D-47A2-AAAE-29D317C6F066'; | |
'ProgramFilesCommonX64' = '6365D5A7-0F0D-45E5-87F6-0DA56B6A4F7D'; | |
'ProgramFilesCommonX86' = 'DE974D24-D9C6-4D3E-BF91-F4455120B917'; | |
'Programs' = 'A77F5D77-2E2B-44C3-A6A2-ABA601054A51'; | |
'Public' = 'DFDF76A2-C82A-4D63-906A-5644AC457385'; | |
'PublicDesktop' = 'C4AA340D-F20F-4863-AFEF-F87EF2E6BA25'; | |
'PublicDocuments' = 'ED4824AF-DCE4-45A8-81E2-FC7965083634'; | |
'PublicDownloads' = '3D644C9B-1FB8-4f30-9B45-F670235F79C0'; | |
'PublicGameTasks' = 'DEBF2536-E1A8-4c59-B6A2-414586476AEA'; | |
'PublicMusic' = '3214FAB5-9757-4298-BB61-92A9DEAA44FF'; | |
'PublicPictures' = 'B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5'; | |
'PublicVideos' = '2400183A-6185-49FB-A2D8-4A392A602BA3'; | |
'QuickLaunch' = '52a4f021-7b75-48a9-9f6b-4b87a210bc8f'; | |
'Recent' = 'AE50C081-EBD2-438A-8655-8A092E34987A'; | |
'RecycleBinFolder' = 'B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC'; | |
'ResourceDir' = '8AD10C31-2ADB-4296-A8F7-E4701232C972'; | |
'RoamingAppData' = '3EB685DB-65F9-4CF6-A03A-E3EF65729F3D'; | |
'SampleMusic' = 'B250C668-F57D-4EE1-A63C-290EE7D1AA1F'; | |
'SamplePictures' = 'C4900540-2379-4C75-844B-64E6FAF8716B'; | |
'SamplePlaylists' = '15CA69B3-30EE-49C1-ACE1-6B5EC372AFB5'; | |
'SampleVideos' = '859EAD94-2E85-48AD-A71A-0969CB56A6CD'; | |
'SavedGames' = '4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4'; | |
'SavedSearches' = '7d1d3a04-debb-4115-95cf-2f29da2920da'; | |
'SEARCH_CSC' = 'ee32e446-31ca-4aba-814f-a5ebd2fd6d5e'; | |
'SEARCH_MAPI' = '98ec0e18-2098-4d44-8644-66979315a281'; | |
'SearchHome' = '190337d1-b8ca-4121-a639-6d472d16972a'; | |
'SendTo' = '8983036C-27C0-404B-8F08-102D10DCFD74'; | |
'SidebarDefaultParts' = '7B396E54-9EC5-4300-BE0A-2482EBAE1A26'; | |
'SidebarParts' = 'A75D362E-50FC-4fb7-AC2C-A8BEAA314493'; | |
'StartMenu' = '625B53C3-AB48-4EC1-BA1F-A1EF4146FC19'; | |
'Startup' = 'B97D20BB-F46A-4C97-BA10-5E3608430854'; | |
'SyncManagerFolder' = '43668BF8-C14E-49B2-97C9-747784D784B7'; | |
'SyncResultsFolder' = '289a9a43-be44-4057-a41b-587a76d7e7f9'; | |
'SyncSetupFolder' = '0F214138-B1D3-4a90-BBA9-27CBC0C5389A'; | |
'System' = '1AC14E77-02E7-4E5D-B744-2EB1AE5198B7'; | |
'SystemX86' = 'D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27'; | |
'Templates' = 'A63293E8-664E-48DB-A079-DF759E0509F7'; | |
'TreeProperties' = '5b3749ad-b49f-49c1-83eb-15370fbd4882'; | |
'UserProfiles' = '0762D272-C50A-4BB0-A382-697DCD729B80'; | |
'UsersFiles' = 'f3ce0f7c-4901-4acc-8648-d5d44b04ef8f'; | |
'Videos' = '18989B1D-99B5-455B-841C-AB7C74E4DDFC'; | |
'Windows' = 'F38BF404-1D43-42F2-9305-67DE0B28FC23'; | |
} | |
# Settings KnownFolders to be in script scope breaks the validator when Import-module is used 2 times. | |
# New-Variable -Name KnownFolders -Value $KnownFolders -Scope Script -Force | |
# class ValidKnownFoldersGenerator : IValidateSetValuesGenerator { | |
# #Preferably I would hide this class but I don't know enough powershell to scope it out of global | |
# [string[]] GetValidValues() { | |
# $Values = $global:KnownFolders.Keys | |
# echo $Values | |
# return $Values | |
# } | |
# } | |
function Set-KnownFolderPath { | |
<# | |
.SYNOPSIS | |
Sets a known folder's path using SHSetKnownFolderPath. | |
.PARAMETER KnownFolder | |
The known folder whose path to set. | |
.PARAMETER Path | |
The path. | |
.INPUTS | |
None. You cannot pipe objects to Set-KnownFolderPath. | |
.OUTPUTS | |
Int. Set-KnownFolderPath returns an int with the return code of SHSetKnownFolderPath | |
.EXAMPLE | |
PS> Set-KnownFolderPath Desktop $ENV:USERPROFILE/Desktop | |
0 | |
.EXAMPLE | |
PS> Set-KnownFolderPath -KnownFolder Desktop -Path $ENV:USERPROFILE/Desktop | |
0 | |
.LINK | |
https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shsetknownfolderpath | |
.LINK | |
https://stackoverflow.com/questions/25709398/set-location-of-special-folders-with-powershell | |
#> | |
Param ( | |
[Parameter(Mandatory = $true)] | |
# [ValidateSet([ValidKnownFoldersGenerator])] | |
[ValidateSet('3DObjects', 'AddNewPrograms', 'AdminTools', 'AppUpdates', 'CDBurning', 'ChangeRemovePrograms', 'CommonAdminTools', 'CommonOEMLinks', 'CommonPrograms', 'CommonStartMenu', 'CommonStartup', 'CommonTemplates', 'ComputerFolder', 'ConflictFolder', 'ConnectionsFolder', 'Contacts', 'ControlPanelFolder', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'Fonts', 'Games', 'GameTasks', 'History', 'InternetCache', 'InternetFolder', 'Links', 'LocalAppData', 'LocalAppDataLow', 'LocalizedResourcesDir', 'Music', 'NetHood', 'NetworkFolder', 'OriginalImages', 'PhotoAlbums', 'Pictures', 'Playlists', 'PrintersFolder', 'PrintHood', 'Profile', 'ProgramData', 'ProgramFiles', 'ProgramFilesX64', 'ProgramFilesX86', 'ProgramFilesCommon', 'ProgramFilesCommonX64', 'ProgramFilesCommonX86', 'Programs', 'Public', 'PublicDesktop', 'PublicDocuments', 'PublicDownloads', 'PublicGameTasks', 'PublicMusic', 'PublicPictures', 'PublicVideos', 'QuickLaunch', 'Recent', 'RecycleBinFolder', 'ResourceDir', 'RoamingAppData', 'SampleMusic', 'SamplePictures', 'SamplePlaylists', 'SampleVideos', 'SavedGames', 'SavedSearches', 'SEARCH_CSC', 'SEARCH_MAPI', 'SearchHome', 'SendTo', 'SidebarDefaultParts', 'SidebarParts', 'StartMenu', 'Startup', 'SyncManagerFolder', 'SyncResultsFolder', 'SyncSetupFolder', 'System', 'SystemX86', 'Templates', 'TreeProperties', 'UserProfiles', 'UsersFiles', 'Videos', 'Windows')] | |
[string]$KnownFolder, | |
[Parameter(Mandatory = $true)] | |
[string]$Path | |
) | |
# Define SHSetKnownFolderPath if it hasn't been defined already | |
$Type = ([System.Management.Automation.PSTypeName]'KnownFolders.SHSetKnownFolderPathPS').Type | |
if (-not $Type) { | |
# http://www.pinvoke.net/default.aspx/shell32/SHSetKnownFolderPath.html | |
$Signature = @' | |
[DllImport("shell32.dll")] | |
public extern static int SHSetKnownFolderPath(ref Guid folderId, uint flags, IntPtr token, [MarshalAs(UnmanagedType.LPWStr)] string path); | |
'@ | |
$Type = Add-Type -MemberDefinition $Signature -Namespace 'KnownFolders' -Name 'SHSetKnownFolderPathPS' -PassThru | |
} | |
# Validate the path | |
if (Test-Path $Path -PathType Container) { | |
# Call SHSetKnownFolderPath | |
return $Type::SHSetKnownFolderPath([ref]$KnownFolders[$KnownFolder], 0, 0, $Path) | |
} | |
else { | |
throw New-Object System.IO.DirectoryNotFoundException "Could not find part of the path $Path." | |
} | |
} | |
function Get-KnownFolderPath { | |
<# | |
.SYNOPSIS | |
Gets a known folder's path using SHGetKnownFolderPath. | |
.PARAMETER KnownFolder | |
The known folder whose path to get. | |
.PARAMETER Path | |
The path. | |
.INPUTS | |
None. You cannot pipe objects to Get-KnownFolderPath. | |
.OUTPUTS | |
Int. Get-KnownFolderPath returns an int with the return code of SHGetKnownFolderPath | |
.EXAMPLE | |
PS> Get-KnownFolderPath Desktop ([ref]$Path) | |
0 | |
.EXAMPLE | |
PS> $Path = "" | |
PS> Get-KnownFolderPath -KnownFolder Desktop -Path ([ref]$Path) | |
0 | |
PS>$Path #Check the value of path | |
C:\Users\user\Desktop | |
.LINK | |
https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath | |
.LINK | |
https://stackoverflow.com/questions/25709398/set-location-of-special-folders-with-powershell | |
#> | |
Param ( | |
[Parameter(Mandatory = $true)] | |
# [ValidateSet([ValidKnownFoldersGenerator])] | |
[ValidateSet('3DObjects', 'AddNewPrograms', 'AdminTools', 'AppUpdates', 'CDBurning', 'ChangeRemovePrograms', 'CommonAdminTools', 'CommonOEMLinks', 'CommonPrograms', 'CommonStartMenu', 'CommonStartup', 'CommonTemplates', 'ComputerFolder', 'ConflictFolder', 'ConnectionsFolder', 'Contacts', 'ControlPanelFolder', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'Fonts', 'Games', 'GameTasks', 'History', 'InternetCache', 'InternetFolder', 'Links', 'LocalAppData', 'LocalAppDataLow', 'LocalizedResourcesDir', 'Music', 'NetHood', 'NetworkFolder', 'OriginalImages', 'PhotoAlbums', 'Pictures', 'Playlists', 'PrintersFolder', 'PrintHood', 'Profile', 'ProgramData', 'ProgramFiles', 'ProgramFilesX64', 'ProgramFilesX86', 'ProgramFilesCommon', 'ProgramFilesCommonX64', 'ProgramFilesCommonX86', 'Programs', 'Public', 'PublicDesktop', 'PublicDocuments', 'PublicDownloads', 'PublicGameTasks', 'PublicMusic', 'PublicPictures', 'PublicVideos', 'QuickLaunch', 'Recent', 'RecycleBinFolder', 'ResourceDir', 'RoamingAppData', 'SampleMusic', 'SamplePictures', 'SamplePlaylists', 'SampleVideos', 'SavedGames', 'SavedSearches', 'SEARCH_CSC', 'SEARCH_MAPI', 'SearchHome', 'SendTo', 'SidebarDefaultParts', 'SidebarParts', 'StartMenu', 'Startup', 'SyncManagerFolder', 'SyncResultsFolder', 'SyncSetupFolder', 'System', 'SystemX86', 'Templates', 'TreeProperties', 'UserProfiles', 'UsersFiles', 'Videos', 'Windows')] | |
[string]$KnownFolder, | |
[Parameter(Mandatory = $true)] | |
[ref]$Path | |
) | |
# Define SHGetKnownFolderPathif it hasn't been defined already | |
$Type = ([System.Management.Automation.PSTypeName]'KnownFolders.SHGetKnownFolderPathPS').Type | |
if (-not $Type) { | |
# http://www.pinvoke.net/default.aspx/shell32/SHGetKnownFolderPath.html | |
$Signature = @' | |
[DllImport("shell32.dll")] | |
public extern static int SHGetKnownFolderPath(ref Guid folderId, uint flags, IntPtr token,[MarshalAs(UnmanagedType.LPWStr)] out string pszPath); | |
'@ | |
$Type = Add-Type -MemberDefinition $Signature -Namespace 'KnownFolders' -Name 'SHGetKnownFolderPathPS' -PassThru | |
} | |
# I am not sure why I need to work around like this instead of passing $Path directly but the value doesn't propegate outside... | |
$_Path = "" | |
$code = $Type::SHGetKnownFolderPath([ref]$KnownFolders[$KnownFolder], 0, 0, [ref]$_Path) | |
$Path.value = $_Path | |
return $code | |
} |
#PS 7.1 | |
<# | |
.SYNOPSIS | |
Requires powershell 7 or later, see other revision for powershell 5. | |
Provides Get and Set functions for KnownFolders | |
.EXAMPLE | |
PS> Set-KnownFolderPath Desktop $ENV:USERPROFILE/Desktop | |
.EXAMPLE | |
PS> $Path="" | |
PS> Get-KnownFolderPath Desktop ([ref]$Path) | |
.LINK | |
https://docs.microsoft.com/en-us/windows/win32/shell/known-folders | |
.LINK | |
https://stackoverflow.com/questions/25709398/set-location-of-special-folders-with-powershell | |
.LINK | |
https://gist.github.com/YoraiLevi/0f333d520f502fdb1244cdf0524db6d2 | |
#> | |
using namespace System.Management.Automation | |
# Define known folder GUIDs | |
$KnownFolders = @{ | |
'3DObjects' = '31C0DD25-9439-4F12-BF41-7FF4EDA38722'; | |
'AddNewPrograms' = 'de61d971-5ebc-4f02-a3a9-6c82895e5c04'; | |
'AdminTools' = '724EF170-A42D-4FEF-9F26-B60E846FBA4F'; | |
'AppUpdates' = 'a305ce99-f527-492b-8b1a-7e76fa98d6e4'; | |
'CDBurning' = '9E52AB10-F80D-49DF-ACB8-4330F5687855'; | |
'ChangeRemovePrograms' = 'df7266ac-9274-4867-8d55-3bd661de872d'; | |
'CommonAdminTools' = 'D0384E7D-BAC3-4797-8F14-CBA229B392B5'; | |
'CommonOEMLinks' = 'C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D'; | |
'CommonPrograms' = '0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8'; | |
'CommonStartMenu' = 'A4115719-D62E-491D-AA7C-E74B8BE3B067'; | |
'CommonStartup' = '82A5EA35-D9CD-47C5-9629-E15D2F714E6E'; | |
'CommonTemplates' = 'B94237E7-57AC-4347-9151-B08C6C32D1F7'; | |
'ComputerFolder' = '0AC0837C-BBF8-452A-850D-79D08E667CA7'; | |
'ConflictFolder' = '4bfefb45-347d-4006-a5be-ac0cb0567192'; | |
'ConnectionsFolder' = '6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD'; | |
'Contacts' = '56784854-C6CB-462b-8169-88E350ACB882'; | |
'ControlPanelFolder' = '82A74AEB-AEB4-465C-A014-D097EE346D63'; | |
'Cookies' = '2B0F765D-C0E9-4171-908E-08A611B84FF6'; | |
'Desktop' = 'B4BFCC3A-DB2C-424C-B029-7FE99A87C641'; | |
'Documents' = 'FDD39AD0-238F-46AF-ADB4-6C85480369C7'; | |
'Downloads' = '374DE290-123F-4565-9164-39C4925E467B'; | |
'Favorites' = '1777F761-68AD-4D8A-87BD-30B759FA33DD'; | |
'Fonts' = 'FD228CB7-AE11-4AE3-864C-16F3910AB8FE'; | |
'Games' = 'CAC52C1A-B53D-4edc-92D7-6B2E8AC19434'; | |
'GameTasks' = '054FAE61-4DD8-4787-80B6-090220C4B700'; | |
'History' = 'D9DC8A3B-B784-432E-A781-5A1130A75963'; | |
'InternetCache' = '352481E8-33BE-4251-BA85-6007CAEDCF9D'; | |
'InternetFolder' = '4D9F7874-4E0C-4904-967B-40B0D20C3E4B'; | |
'Links' = 'bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968'; | |
'LocalAppData' = 'F1B32785-6FBA-4FCF-9D55-7B8E7F157091'; | |
'LocalAppDataLow' = 'A520A1A4-1780-4FF6-BD18-167343C5AF16'; | |
'LocalizedResourcesDir' = '2A00375E-224C-49DE-B8D1-440DF7EF3DDC'; | |
'Music' = '4BD8D571-6D19-48D3-BE97-422220080E43'; | |
'NetHood' = 'C5ABBF53-E17F-4121-8900-86626FC2C973'; | |
'NetworkFolder' = 'D20BEEC4-5CA8-4905-AE3B-BF251EA09B53'; | |
'OriginalImages' = '2C36C0AA-5812-4b87-BFD0-4CD0DFB19B39'; | |
'PhotoAlbums' = '69D2CF90-FC33-4FB7-9A0C-EBB0F0FCB43C'; | |
'Pictures' = '33E28130-4E1E-4676-835A-98395C3BC3BB'; | |
'Playlists' = 'DE92C1C7-837F-4F69-A3BB-86E631204A23'; | |
'PrintersFolder' = '76FC4E2D-D6AD-4519-A663-37BD56068185'; | |
'PrintHood' = '9274BD8D-CFD1-41C3-B35E-B13F55A758F4'; | |
'Profile' = '5E6C858F-0E22-4760-9AFE-EA3317B67173'; | |
'ProgramData' = '62AB5D82-FDC1-4DC3-A9DD-070D1D495D97'; | |
'ProgramFiles' = '905e63b6-c1bf-494e-b29c-65b732d3d21a'; | |
'ProgramFilesX64' = '6D809377-6AF0-444b-8957-A3773F02200E'; | |
'ProgramFilesX86' = '7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E'; | |
'ProgramFilesCommon' = 'F7F1ED05-9F6D-47A2-AAAE-29D317C6F066'; | |
'ProgramFilesCommonX64' = '6365D5A7-0F0D-45E5-87F6-0DA56B6A4F7D'; | |
'ProgramFilesCommonX86' = 'DE974D24-D9C6-4D3E-BF91-F4455120B917'; | |
'Programs' = 'A77F5D77-2E2B-44C3-A6A2-ABA601054A51'; | |
'Public' = 'DFDF76A2-C82A-4D63-906A-5644AC457385'; | |
'PublicDesktop' = 'C4AA340D-F20F-4863-AFEF-F87EF2E6BA25'; | |
'PublicDocuments' = 'ED4824AF-DCE4-45A8-81E2-FC7965083634'; | |
'PublicDownloads' = '3D644C9B-1FB8-4f30-9B45-F670235F79C0'; | |
'PublicGameTasks' = 'DEBF2536-E1A8-4c59-B6A2-414586476AEA'; | |
'PublicMusic' = '3214FAB5-9757-4298-BB61-92A9DEAA44FF'; | |
'PublicPictures' = 'B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5'; | |
'PublicVideos' = '2400183A-6185-49FB-A2D8-4A392A602BA3'; | |
'QuickLaunch' = '52a4f021-7b75-48a9-9f6b-4b87a210bc8f'; | |
'Recent' = 'AE50C081-EBD2-438A-8655-8A092E34987A'; | |
'RecycleBinFolder' = 'B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC'; | |
'ResourceDir' = '8AD10C31-2ADB-4296-A8F7-E4701232C972'; | |
'RoamingAppData' = '3EB685DB-65F9-4CF6-A03A-E3EF65729F3D'; | |
'SampleMusic' = 'B250C668-F57D-4EE1-A63C-290EE7D1AA1F'; | |
'SamplePictures' = 'C4900540-2379-4C75-844B-64E6FAF8716B'; | |
'SamplePlaylists' = '15CA69B3-30EE-49C1-ACE1-6B5EC372AFB5'; | |
'SampleVideos' = '859EAD94-2E85-48AD-A71A-0969CB56A6CD'; | |
'SavedGames' = '4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4'; | |
'SavedSearches' = '7d1d3a04-debb-4115-95cf-2f29da2920da'; | |
'SEARCH_CSC' = 'ee32e446-31ca-4aba-814f-a5ebd2fd6d5e'; | |
'SEARCH_MAPI' = '98ec0e18-2098-4d44-8644-66979315a281'; | |
'SearchHome' = '190337d1-b8ca-4121-a639-6d472d16972a'; | |
'SendTo' = '8983036C-27C0-404B-8F08-102D10DCFD74'; | |
'SidebarDefaultParts' = '7B396E54-9EC5-4300-BE0A-2482EBAE1A26'; | |
'SidebarParts' = 'A75D362E-50FC-4fb7-AC2C-A8BEAA314493'; | |
'StartMenu' = '625B53C3-AB48-4EC1-BA1F-A1EF4146FC19'; | |
'Startup' = 'B97D20BB-F46A-4C97-BA10-5E3608430854'; | |
'SyncManagerFolder' = '43668BF8-C14E-49B2-97C9-747784D784B7'; | |
'SyncResultsFolder' = '289a9a43-be44-4057-a41b-587a76d7e7f9'; | |
'SyncSetupFolder' = '0F214138-B1D3-4a90-BBA9-27CBC0C5389A'; | |
'System' = '1AC14E77-02E7-4E5D-B744-2EB1AE5198B7'; | |
'SystemX86' = 'D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27'; | |
'Templates' = 'A63293E8-664E-48DB-A079-DF759E0509F7'; | |
'TreeProperties' = '5b3749ad-b49f-49c1-83eb-15370fbd4882'; | |
'UserProfiles' = '0762D272-C50A-4BB0-A382-697DCD729B80'; | |
'UsersFiles' = 'f3ce0f7c-4901-4acc-8648-d5d44b04ef8f'; | |
'Videos' = '18989B1D-99B5-455B-841C-AB7C74E4DDFC'; | |
'Windows' = 'F38BF404-1D43-42F2-9305-67DE0B28FC23'; | |
} | |
# Settings KnownFolders to be in script scope breaks the validator when Import-module is used 2 times. | |
# New-Variable -Name KnownFolders -Value $KnownFolders -Scope Script -Force | |
class ValidKnownFoldersGenerator : IValidateSetValuesGenerator { | |
#Preferably I would hide this class but I don't know enough powershell to scope it out of global | |
[string[]] GetValidValues() { | |
$Values = $global:KnownFolders.Keys | |
echo $Values | |
return $Values | |
} | |
} | |
echo $KnownFolders | |
function Set-KnownFolderPath { | |
<# | |
.SYNOPSIS | |
Sets a known folder's path using SHSetKnownFolderPath. | |
.PARAMETER KnownFolder | |
The known folder whose path to set. | |
.PARAMETER Path | |
The path. | |
.INPUTS | |
None. You cannot pipe objects to Set-KnownFolderPath. | |
.OUTPUTS | |
Int. Set-KnownFolderPath returns an int with the return code of SHSetKnownFolderPath | |
.EXAMPLE | |
PS> Set-KnownFolderPath Desktop $ENV:USERPROFILE/Desktop | |
0 | |
.EXAMPLE | |
PS> Set-KnownFolderPath -KnownFolder Desktop -Path $ENV:USERPROFILE/Desktop | |
0 | |
.LINK | |
https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shsetknownfolderpath | |
.LINK | |
https://stackoverflow.com/questions/25709398/set-location-of-special-folders-with-powershell | |
#> | |
Param ( | |
[Parameter(Mandatory = $true)] | |
[ValidateSet([ValidKnownFoldersGenerator])] | |
# [ValidateSet('3DObjects', 'AddNewPrograms', 'AdminTools', 'AppUpdates', 'CDBurning', 'ChangeRemovePrograms', 'CommonAdminTools', 'CommonOEMLinks', 'CommonPrograms', 'CommonStartMenu', 'CommonStartup', 'CommonTemplates', 'ComputerFolder', 'ConflictFolder', 'ConnectionsFolder', 'Contacts', 'ControlPanelFolder', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'Fonts', 'Games', 'GameTasks', 'History', 'InternetCache', 'InternetFolder', 'Links', 'LocalAppData', 'LocalAppDataLow', 'LocalizedResourcesDir', 'Music', 'NetHood', 'NetworkFolder', 'OriginalImages', 'PhotoAlbums', 'Pictures', 'Playlists', 'PrintersFolder', 'PrintHood', 'Profile', 'ProgramData', 'ProgramFiles', 'ProgramFilesX64', 'ProgramFilesX86', 'ProgramFilesCommon', 'ProgramFilesCommonX64', 'ProgramFilesCommonX86', 'Programs', 'Public', 'PublicDesktop', 'PublicDocuments', 'PublicDownloads', 'PublicGameTasks', 'PublicMusic', 'PublicPictures', 'PublicVideos', 'QuickLaunch', 'Recent', 'RecycleBinFolder', 'ResourceDir', 'RoamingAppData', 'SampleMusic', 'SamplePictures', 'SamplePlaylists', 'SampleVideos', 'SavedGames', 'SavedSearches', 'SEARCH_CSC', 'SEARCH_MAPI', 'SearchHome', 'SendTo', 'SidebarDefaultParts', 'SidebarParts', 'StartMenu', 'Startup', 'SyncManagerFolder', 'SyncResultsFolder', 'SyncSetupFolder', 'System', 'SystemX86', 'Templates', 'TreeProperties', 'UserProfiles', 'UsersFiles', 'Videos', 'Windows')] | |
[string]$KnownFolder, | |
[Parameter(Mandatory = $true)] | |
[string]$Path | |
) | |
# Define SHSetKnownFolderPath if it hasn't been defined already | |
$Type = ([System.Management.Automation.PSTypeName]'KnownFolders.SHSetKnownFolderPathPS').Type | |
if (-not $Type) { | |
# http://www.pinvoke.net/default.aspx/shell32/SHSetKnownFolderPath.html | |
$Signature = @' | |
[DllImport("shell32.dll")] | |
public extern static int SHSetKnownFolderPath(ref Guid folderId, uint flags, IntPtr token, [MarshalAs(UnmanagedType.LPWStr)] string path); | |
'@ | |
$Type = Add-Type -MemberDefinition $Signature -Namespace 'KnownFolders' -Name 'SHSetKnownFolderPathPS' -PassThru | |
} | |
# Validate the path | |
if (Test-Path $Path -PathType Container) { | |
# Call SHSetKnownFolderPath | |
return $Type::SHSetKnownFolderPath([ref]$KnownFolders[$KnownFolder], 0, 0, $Path) | |
} | |
else { | |
throw New-Object System.IO.DirectoryNotFoundException "Could not find part of the path $Path." | |
} | |
} | |
function Get-KnownFolderPath { | |
<# | |
.SYNOPSIS | |
Gets a known folder's path using SHGetKnownFolderPath. | |
.PARAMETER KnownFolder | |
The known folder whose path to get. | |
.PARAMETER Path | |
The path. | |
.INPUTS | |
None. You cannot pipe objects to Get-KnownFolderPath. | |
.OUTPUTS | |
Int. Get-KnownFolderPath returns an int with the return code of SHGetKnownFolderPath | |
.EXAMPLE | |
PS> Get-KnownFolderPath Desktop ([ref]$Path) | |
0 | |
.EXAMPLE | |
PS> $Path = "" | |
PS> Get-KnownFolderPath -KnownFolder Desktop -Path ([ref]$Path) | |
0 | |
PS>$Path #Check the value of path | |
C:\Users\user\Desktop | |
.LINK | |
https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath | |
.LINK | |
https://stackoverflow.com/questions/25709398/set-location-of-special-folders-with-powershell | |
#> | |
Param ( | |
[Parameter(Mandatory = $true)] | |
[ValidateSet([ValidKnownFoldersGenerator])] | |
# [ValidateSet('3DObjects', 'AddNewPrograms', 'AdminTools', 'AppUpdates', 'CDBurning', 'ChangeRemovePrograms', 'CommonAdminTools', 'CommonOEMLinks', 'CommonPrograms', 'CommonStartMenu', 'CommonStartup', 'CommonTemplates', 'ComputerFolder', 'ConflictFolder', 'ConnectionsFolder', 'Contacts', 'ControlPanelFolder', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'Fonts', 'Games', 'GameTasks', 'History', 'InternetCache', 'InternetFolder', 'Links', 'LocalAppData', 'LocalAppDataLow', 'LocalizedResourcesDir', 'Music', 'NetHood', 'NetworkFolder', 'OriginalImages', 'PhotoAlbums', 'Pictures', 'Playlists', 'PrintersFolder', 'PrintHood', 'Profile', 'ProgramData', 'ProgramFiles', 'ProgramFilesX64', 'ProgramFilesX86', 'ProgramFilesCommon', 'ProgramFilesCommonX64', 'ProgramFilesCommonX86', 'Programs', 'Public', 'PublicDesktop', 'PublicDocuments', 'PublicDownloads', 'PublicGameTasks', 'PublicMusic', 'PublicPictures', 'PublicVideos', 'QuickLaunch', 'Recent', 'RecycleBinFolder', 'ResourceDir', 'RoamingAppData', 'SampleMusic', 'SamplePictures', 'SamplePlaylists', 'SampleVideos', 'SavedGames', 'SavedSearches', 'SEARCH_CSC', 'SEARCH_MAPI', 'SearchHome', 'SendTo', 'SidebarDefaultParts', 'SidebarParts', 'StartMenu', 'Startup', 'SyncManagerFolder', 'SyncResultsFolder', 'SyncSetupFolder', 'System', 'SystemX86', 'Templates', 'TreeProperties', 'UserProfiles', 'UsersFiles', 'Videos', 'Windows')] | |
[string]$KnownFolder, | |
[Parameter(Mandatory = $true)] | |
[ref]$Path | |
) | |
# Define SHGetKnownFolderPathif it hasn't been defined already | |
$Type = ([System.Management.Automation.PSTypeName]'KnownFolders.SHGetKnownFolderPathPS').Type | |
if (-not $Type) { | |
# http://www.pinvoke.net/default.aspx/shell32/SHGetKnownFolderPath.html | |
$Signature = @' | |
[DllImport("shell32.dll")] | |
public extern static int SHGetKnownFolderPath(ref Guid folderId, uint flags, IntPtr token,[MarshalAs(UnmanagedType.LPWStr)] out string pszPath); | |
'@ | |
$Type = Add-Type -MemberDefinition $Signature -Namespace 'KnownFolders' -Name 'SHGetKnownFolderPathPS' -PassThru | |
} | |
# I am not sure why I need to work around like this instead of passing $Path directly but the value doesn't propegate outside... | |
$_Path = "" | |
$code = $Type::SHGetKnownFolderPath([ref]$KnownFolders[$KnownFolder], 0, 0, [ref]$_Path) | |
$Path.value = $_Path | |
return $code | |
} |
Import-Module ./KnownFolderPathPS5.ps1 | |
$Path="" | |
Get-KnownFolderPath Desktop ([ref]$Path) | |
echo $Path | |
Set-KnownFolderPath Desktop $ENV:USERPROFILE/Desktop | |
Get-KnownFolderPath Desktop ([ref]$Path) | |
echo $Path |
Hello , when I import , it retrun this
thkPS C:\Users\36554\Desktop> Import-Module ./KnownFolderPath.ps1 Location C:\Users\36554\Desktop\KnownFolderPath.ps1:112 character: 36 + class ValidKnownFoldersGenerator : IValidateSetValuesGenerator { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Type not found [IValidateSetValuesGenerator]。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : TypeNotFound
my powershell:
PS C:\Users\36554\Desktop> $PSVersionTable Name Value ---- ----- PSVersion 5.1.19041.906 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.19041.906 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1
This version runs on
PS C:\Users\user> $PSVersionTable
Name Value
---- -----
PSVersion 7.1.3
PSEdition Core
GitCommitId 7.1.3
OS Microsoft Windows 10.0.19042
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
i'll add a version running on 5.1
Question #1 - Does this still work on Windows 11?
Question #2a&b - I must import the code into PowerShell to use it? -- It clearly appears to be so. Once imported is it stored across PowerShell Sessions?
Question 3 - I am new to PowerShell but $ENV:USERPROFILE is the current path to the folder (C:\Users|{userID}\Desktop) If my echo test was correct. Where does one place the path to be assigned such as {someDrive}:{somePath}\Desktop?
Question #4 - Is only one folder is "moved" for each invocation of Set-KnownFolderPath? I believe that is so regardless of the inclusion of the "-KnownFolder" keyword.
Question #5 - Is the data moved and a new folder or folders created if necessary or is that a separate requirement? From the SHSetKnownFolderPath documentation it appears the data is moved.
Thanks
Question #1 - Does this still work on Windows 11?
It should work, I believe i ran it once on my win11 setup but there is an issue with the explorer.exe refreshing even in the properties until restart… it needs another refresh call of some sort.. so just restart after or research how to do that weird refresh call
Question #2a&b - I must import the code into PowerShell to use it? -- It clearly appears to be so. Once imported is it stored across PowerShell Sessions?
This code defines functions, you need to either paste them into your terminal and use them or input it into a power shell module and use it from an imported module, depending on your use case i could suggest either thing. copy paste and adapting it for you own use case is suggested
Question 3 - I am new to PowerShell but $ENV:USERPROFILE is the current path to the folder (C:\Users|{userID}\Desktop) If my echo test was correct. Where does one place the path to be assigned such as {someDrive}:{somePath}\Desktop?
instead of the $env:UserProfile/whatever type the path, “D:/path/to/Desktop”
you can copy the path the file explorer and wrap it with single' or double” quotes
Question #4 - Is only one folder is "moved" for each invocation of Set-KnownFolderPath? I believe that is so regardless of the inclusion of the "-KnownFolder" keyword.
Yes it sets the “location” property of a single “known folder” per each call, to set the location of documents and download you execute it once for documents and once for downloads. this command DOES NOT move files. sets the location like in the properties menu (you might need a restart to see the effect)
Question #5 - Is the data moved and a new folder or folders created if necessary or is that a separate requirement? From the SHSetKnownFolderPath documentation it appears the data is moved.
This doesn’t create a new folder nor it moves the files, you need to call more powershell commands to do these or do it manually
Ask away if you need more help @dshuman52
Hello , when I import , it retrun this
thk
my powershell: