Automating Web URLs as Start Menu Links

Posted on Updated on

In my previous post on Creating Web URLs as Start Menu Links, I outlined details how to manually create links to URLs (as seen in the images below).  While this does work, most folks in the systems management community would prefer to automate this link creations.  The following PowerShell script can be used to create a custom start menu link for all users.

Note that a problem that you may encounter is the link not being displayed in the grouping.  This could be caused by having two .lnk files with the same target path pointing to the same URL.

# Create a Shortcut with Windows PowerShell
$oWScriptShell = New-Object -ComObject WScript.Shell
$sTargetFile = "C:\Windows\explorer.exe"
$sShortcutFile = $oWScriptShell.SpecialFolders("AllUsersPrograms") + "\Links\t3chn1ck.lnk"
# Note: to open URL in a specific browser like Edge, add in front of the URL Microsoft-edge:
$sURL = "http://t3chn1ck.com"

#Delete existing shortcut if exists
If (Test-Path $sShortcutFile){
Remove-Item $sShortcutFile

$oShortcut = $oWScriptShell.CreateShortcut($sShortcutFile)
$oShortcut.IconLocation = "explorer.exe,20"
$oShortcut.TargetPath = $sTargetFile
$oShortcut.Arguments = $sURL

urldemo5 urldemo4

Testing Windows 10 Assigned Access

Posted on Updated on

Based upon the information in article Set up a kiosk on Windows 10, it is possible to quickly setup a Windows 10 UWP app to run with Assigned Access.  From that article, I’ve outlined (below) the quick-start steps for testing purposes.

  1. Login to Windows with an account that has local admin rights.
  2. Create a local user account (such as “kiosk”) with a password and do not grant the account local admin privileges.
  3. Sign out of Windows.
  4. Login to Windows with the kiosk user account so that it builds the profile.
  5. If the tablet has physical keyboard capabilities, then change that user to use Tablet Mode and log out.  Otherwise, skip this step.
  6. Login to Windows with the local admin account.
  7. Edit the registry to enable auto login of the kiosk account.
  8. Use the PowerShell script in this article to get the AUMID for the UWP app.
    • If you’re just looking for a quick example, use the MSN News app with ID – Microsoft.BingNews_8wekyb3d8bbwe!AppexNews
  9. Based upon the information in the previous step, run a PowerShell command in this article to set the kiosk user to have assigned access to your UWP app.
  10. Verify that the user was properly assigned to launch the application by:
    • Start > Settings > User accounts > Family and other users
    • Under the “Other Users” section, select “Set up assigned access”
    • Ensure the user shows the application

Also, to sideload a UWP application, see this information: https://msdn.microsoft.com/en-us/windows/uwp/packaging/packaging-uwp-apps#sideload-your-app-package.

More information on best practices for developing UWP apps for Assigned Access: https://msdn.microsoft.com/en-us/library/windows/hardware/mt633799.aspx

Remove Universal Apps During ConfigMgr OSD

Posted on Updated on

As part of a systems management strategy for Windows 10, many organization may choose to uninstall Universal Apps. During OSD for ConfigMgr, this uninstall process use a simple PowerShell script (as shown below) to execute the commands for removing the targeted Universal Apps.  While this does command does “remove” the Apps as seen in the event logs (Apps and Services > Microsoft > Windows > AppXDeployment-Server) the Apps are regenerated upon the first logon of a user.

Get-AppXPackage -Name *bing* -AllUsers | Remove-AppXPackage

Furthermore, there is an option (UniversalAppUninstall) within a WICD Provisioning Package.  There are times when this option would be a better approach, but I have not been successful in having it function to uninstall Apps.  Unfortunately, information is scant on this topic.

A Solution

Stumbling around for other who may have found other means to address this situation,  Jörgen Nilsson (Microsoft MVP) has a PowerShell script which does completely remove those undesired Universal Apps.  The key difference is that his script uses the Remove-AppxProvisionedPackage cmdlet against the full package name.

The variable for AppList that I use this:

$AppsList = "Microsoft.BingFinance","Microsoft.BingNews","Microsoft.BingWeather","Microsoft.XboxApp","Microsoft.SkypeApp","Microsoft.MicrosoftSolitaireCollection","Microsoft.BingSports","Microsoft.ZuneMusic","Microsoft.ZuneVideo","Microsoft.Windows.Photos","Microsoft.People","Microsoft.MicrosoftOfficeHub","Microsoft.WindowsMaps","microsoft.windowscommunicationsapps","Microsoft.Getstarted","Microsoft.3DBuilder"

To execute the script as part of a Task Sequence in ConfigMgr, it’s as easy as having placing the script file in a classic Package, and having the step “Execute PowerShell Script” with the Bypass option set.



ConfigMgr 2012 R2 PowerShell to Install SMP Role

Posted on Updated on

In a recent customer engagement, we needed to mass deploy the State Migration Point (SMP) role to nearly 70 servers.  After completing about a dozen of these one by one, I thought PowerShell would be a much faster way to accomplish the end goal.  The below script can be used as an example for finding existing site systems that do not have the SMP role installed, while allowing it to skip servers with certain names (in this example, it skips servers that begin with TEST in the name).


import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')
# Site Code + :
$SiteCode = "GAL:"
Set-Location $SiteCode

#Properties for Setting the SMP Role
$UsmtDrivePath = "F:\USMT"
$MaxNumClients = 100
$MinFreeSpace = 3
$TimeDeleteAfterDays = 5

$SiteSystemServers = Get-CMSiteSystemServer
write-host $SiteSystemServers.Count

ForEach ($Server in $SiteSystemServers) {
    $ServerName = $Server.NetworkOSPath.Replace("\\", " ")

    $CheckSMP = Get-CMSiteRole -RoleName "SMS State Migration Point" -SiteSystemServerName $ServerName
    #write-host $CheckSMP.Count

	# If SMP Count is zero, SMP not installed
    If ($CheckSMP.Count -eq 0) {
        If ($ServerName.ToUpper().StartsWith("TEST")) {
            # Do Nothing, skip this type of server
        } Else {
            Write-host "No SMP Role, installing on" $ServerName

            $Folder = New-CMStorageFolder -StorageFolderName $UsmtDrivePath -MaximumClientNumber _
				$MaxNumClients -MinimumFreeSpace $MinFreeSpace -SpaceUnit Gigabyte

			Add-CMStateMigrationPoint -SiteSystemServerName $ServerName -StorageFolder $Folder _
				-AllowFallbackSourceLocationForContent $False -EnableRestoreOnlyMode $False -SiteCode $SiteCode _
				-TimeDeleteAfter $TimeDeleteAfterDays -TimeUnit Days
    } Else {
        Write-host "SMP Role installed, skipping server" $ServerName

Finding ConfigMgr Collections with Queries

Posted on Updated on

Using ConfigMgr 2012 R2 (and newer), the following PowerShell script can be used to identify which device collections have a query in them, and those that do not.

Example output:



import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')
# Site Code + :
Set-Location "GAL:"

$CollectionList = Get-CMDeviceCollection

ForEach ($Collection in $CollectionList) {
    $RuleName = (Get-CMDeviceCollectionQueryMembershipRule -CollectionId $Collection.CollectionID).RuleName

    If ([string]::IsNullOrEmpty($RuleName)) {
        write-host "NO Query: " $Collection.CollectionID "," $Collection.Name -foregroundcolor Red
    } Else {
        write-host "YES Query:" $Collection.CollectionID "," $Collection.Name ", Query name:" $RuleName

Azure AD – PowerShell Script to Change UPN of All Users in a Group

Posted on Updated on

Imagine that if users in a domain have a UPN suffix which is not a public domain, such as @company.local instead of @company.com.  When those users synchronize into Azure AD for EMS, Intune, O365, etc., then the users’ UPNs will be @company.onmicrosoft.com instead of a friendly @company.com UPN for logging into portals or for enrolling devices.

This is an instance that recently occurred for a customer.  There are plenty of PowerShell examples around for how to change the UPN of users in Azure AD.  However, this customer wanted the ability to only change the users that were part of a specific AD group, rather than the entire organization.

The following PowerShell script can do exactly just that.  But please use extreme caution and thoroughly test the script first as well as the impact to those users and the Microsoft cloud technologies which they use.  There are high risks and many possible negative side effects.  Use this script at your own risk.

# This script will change the UPN for the user members of an AD group
$AdGrp = "EMS_Users"
$oldSuffix = "@company.onmicrosoft.com"
$newSuffix = "@company.com"

# Get the AD Group in Azure
$AzAdGrp = Get-MsolGroup -All | Where-Object { $_.DisplayName -eq $AdGrp }
$AzAdGrp_members = Get-MsolGroupMember -All -GroupObjectId $AzAdGrp.ObjectId
write-host "Total members of group: " $AzAdGrp_members.Count

# Create array of users to change
# Example command to test only a portion of the users in the group:
$users = Get-MsolGroupMember -All -GroupObjectId $AzAdGrp.ObjectId | Get-MsolUser | Where-Object { $_.UserPrincipalName -like "*john.doe*"}
# Command to run for all users in the group:
# $users = Get-MsolGroupMember -All -GroupObjectId $AzAdGrp.ObjectId | Get-MsolUser

# Change UPN of users
$users | ForEach-Object {
    $newUpn = $_.UserPrincipalName.Replace($oldSuffix,$newSuffix)
    Set-MsolUserPrincipalName -NewUserPrincipalName $newUpn -UserPrincipalName $_.UserPrincipalName
    Write-host "New UPN assigned: " $newUpn


App-V 5.0 bulk add and publish applications

Posted on Updated on

Piggybacking on Aaron Parker’s blog post for App-V 5 PowerShell One Liners – Adding and Publishing App-V Server Packages, I’ve extended the usage of the script to parse all sub-directories of a folder to add/publish any .appv package.

$grpName = "lab\Domain Users"
$appContentShare = "\\appv5-server\content-share"
# Get the list of AppV files
Set-Location $appContentShare
$filesList = get-childitem $_.DirectoryName -include *.appv -recurse

# Bulk import/publish/grant access
ForEach ($file in $filesList) {
   Import-AppvServerPackage -PackagePath $filesList | Publish-AppvServerPackage -Verbose | Grant-AppvServerPackage -Groups $grpName -Verbose

And that’s all it takes!