Add URL to customized Windows 10 Start Menu

September 1, 2016

Hi,

Since more and more of our customers are adopting Windows 10 in their environment we start to learn more tricks every day.

An important component of Windows 10 is the start menu. Administrators could apply a default startmenu layout for all users by using a GPO but downside of this approach is that the user isn’t able to add any custom applications himself. That’s why I prefer to set the startlayout during the Windows 10 deployment task sequence using a Powershell script.

Afterwards the default layout is set when the user first logs in, from then on the user can edit his start menu as he likes. Adding “classical” applications such as Word, Excel and Powerpoint is quite easy as those applications are already present when the user first logs in. Adding a shortcut to a website might be a little bit harder, in this post I’ll be explaining the steps that need to be taken to accomplish this. It’s a combination of Powershell, SCCM  (also applicable for MDT) and Group Policy Preferences. Let’s get started

First of all start by customizing the start menu as you like on a test machine. The start menu I want is the one shown below. We’ll be focusing on the highlighted icon in the start menu as this is a URL, other shortcuts are applications.

Screenshot_1

When the start layout is finished, launch powershell and execute the following command to export the startlayout:

Export-Startlayout -Path “C:\windows\temp\Startlayout.xml”

The XML generated looks as follows (text in bold is related to the Citrix URL):

<LayoutModificationTemplate Version=”1″ xmlns=”http://schemas.microsoft.com/Start/2014/LayoutModification”&gt;
<LayoutOptions StartTileGroupCellWidth=”6″ />
<DefaultLayoutOverride>
<StartLayoutCollection>
<defaultlayout:StartLayout GroupCellWidth=”6″ xmlns:defaultlayout=”http://schemas.microsoft.com/Start/2014/FullDefaultLayout”&gt;
<start:Group Name=”Webbrowsers” xmlns:start=”http://schemas.microsoft.com/Start/2014/StartLayout”&gt;
<start:DesktopApplicationTile Size=”2×2″ Column=”0″ Row=”0″ DesktopApplicationID=”Microsoft.InternetExplorer.Default” />
</start:Group>
<start:Group Name=”Office ” xmlns:start=”http://schemas.microsoft.com/Start/2014/StartLayout”&gt;
<start:DesktopApplicationTile Size=”2×2″ Column=”2″ Row=”0″ DesktopApplicationID=”{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}\Microsoft Office\Office15\WINWORD.EXE” />
<start:DesktopApplicationTile Size=”2×2″ Column=”0″ Row=”0″ DesktopApplicationID=”Microsoft.Office.OUTLOOK.EXE.15″ />
<start:DesktopApplicationTile Size=”2×2″ Column=”0″ Row=”2″ DesktopApplicationID=”{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}\Microsoft Office\Office15\POWERPNT.EXE” />
<start:DesktopApplicationTile Size=”2×2″ Column=”2″ Row=”2″ DesktopApplicationID=”{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}\Microsoft Office\Office15\EXCEL.EXE” />
</start:Group>
<start:Group Name=”” xmlns:start=”http://schemas.microsoft.com/Start/2014/StartLayout”&gt;
<start:DesktopApplicationTile Size=”2×2″ Column=”2″ Row=”0″ DesktopApplicationID=”Microsoft.SoftwareCenter.DesktopToasts” />
<start:DesktopApplicationTile Size=”2×2″ Column=”0″ Row=”0″ DesktopApplicationID=”Microsoft.Windows.ControlPanel” />
</start:Group>
<start:Group Name=”” xmlns:start=”http://schemas.microsoft.com/Start/2014/StartLayout”&gt;
<start:DesktopApplicationTile Size=”2×2″ Column=”0″ Row=”0″ DesktopApplicationID=”https://citrix.contoso.com&#8221; />
</start:Group>
</defaultlayout:StartLayout>
</StartLayoutCollection>
</DefaultLayoutOverride>
</LayoutModificationTemplate>

Now create an SCCM Package containing the XML file and a Powershell script with the following content:

Import-StartLayout -LayoutPath $PSScriptroot\StartLayout.xml -MountPath $env:systemdrive\

Now this can be executed using a Run Powershell Script during the SCCM OSD task sequence.

Without performing further actions when a user first logs in the start menu will be generated but the URL to citrix.contoso.com will not be present. To make sure it’s there we need to create a Group Policy Preference to put the exact URL in the start menu for the user. Pay close attention because the target URL specified in the GPP must EXACTLY match the value of DesktopApplicationID (without the “”)

Screenshot_2

Now when the user (for which the GPP is applied) logs on for the first time on a Windows 10 computer, the default Start layout will be applied properly and the URL will also appear.

Hope this helps!

 

Best regards,

Bert

 

 


Configuration Manager 2012 R2 Powershell Application Detection Method #RDProud

July 2, 2015

Hi all,

This blog post describes how to enable .NET Framework 3.5 on Windows 8.1 after the computers already have been deployed.This can be quite annoying because the SXS source folder is needed when installing + this bug (https://support.microsoft.com/en-us/kb/3005628) can also kick in.

The installation is done using an SCCM application containing an installation powershell script and powershell detection method. An easier alternative is using a package and task sequence to run the powershell script (no detection method needed here). Using the application has the advantage that it can be used as dependency and requirements can be added.

The installation script contains different phases

  • Downloading the source to a local folder in C:\windows\temp\NetFX3
    • This folder contains the installation powershell script and the SXS folder from the Windows 8.1 PRO ISO
  • Installing KB2966828 (to avoid the bug)
  • Enable .NET Framework using the downloaded SXS folder as source
  • Detect if .NET Framework was installed successfully
  • Delete temp folder C:\windows\temp\NetFX3

First of all a little thing about using Powershell as an Application Detection Method

The main purpose is to make sure the detection method exits with exit code = 0 (no errors during the script)  + Depending on the value of STDOUT (Write-Output) the detection method will return that the application is installed or not installed.

Script exit code Data read from STDOUT Data read from STDERR Script result Application detection state
0 Empty Empty Success Not installed
0 Not empty Empty Success Installed

Additional details: http://blog.kloud.com.au/2014/08/12/powershell-detection-method-for-sccm-2012-application-compliance-management/

Now we’ll try to apply this to the .NET Framework 3.5 feature we want to get installed here, the script I use is this:

$Framework = Get-windowsoptionalfeature -FeatureName NetFx3 -Online | Select-Object -ExpandProperty State

if ($Framework -eq “Disabled”)

{

  exit 0

}

else

{

  Write-Host “.NET Enabled”

  exit 0

}

This script is quite easy to understand and does the following

  • If .NET is not installed (disabled): exit script with exit code 0 –> Detection method sees this as “Application Not Installed”:
    • Exit code = 0
    • STDOUT (Write-Host) = Empty
  • If .NET is installed (enabled): exit script with exit code 0 –> Detection method sees this as “Application Installed”:
    • Exit code = 0
    • STDOUT (Write-Host) = Not Empty

Now let’s start adding this into SCCM: Create an Application and give it a suitable name. When creating a Deployment type give in the path to the source and the commandline. This is the commandline I used: “Powershell.exe -executionpolicy Bypass -file .\install.ps1” (without quotes)

02072015_1

When prompted for the detection method, select “Use a custom script to detect the presence of this deployment type and Click Edit, Select powershell and copy the detection method script in here

02072015_2

Finish creating the deployment type adding needed requirements (here I have added Operating System = Windows 8.1 x64)

After the application is created, update distribution points, deploy it to a test machine and see the result

Using the “Retrieve Machine Policy” on the test client we should rapidly see the new deployment, but this didn’t happen. I went to look into the ConfigMgr Client logs and found something interesting in the AppDiscovery.log

The Detection method couldn’t be run because it was not signed “CScriptHandler::DiscoverApp failed (0x87d00327).” I stumbled upon this post by someone who experienced the same error http://www.petervanderwoude.nl/post/deployment-of-configuration-baseline-failed-with-error-script-is-not-signed-in-configmgr-2012/. So I did what he highlighted: Enabling the Powershell Bypass option for the ConfigMgr Client.

A next test should result in the application being successfully added in the Software Center doesn’t it? Yes, it’s there but it says “Installed” while the .NET Framework wasn’t installed . Let’s go back to the AppDiscovery.log. Now no errors were listed but only warnings stating the script returned some error message (The application is detected as shown in the log “Detected App Deployment Type…”, but the application is not installed)

02072015_4

This one was tackled by disabling by unchecking “Run script as 32-bit process on 64-bit clients” on the detection method

02072015_5

After this little adjustment and another try everything looked good. The application was listed as “Available” in Software Center and the AppDiscovery.log showed the following: The App Deployment type was not detected.

02072015_6

Great! Hope this helps in helping you guys out!

Best regards,

B


Orchestrator run .NET version

June 22, 2015

 

All,

We’re using a simple script to enumerate all AD groups containing info in a notes field in Orchestrator.

The script is this :

import-module activedirectory -force

$ArrayProcessList = @()

$Searchbase = “OU=Security Groups,OU=Groups,DC=localdomain,DC=com”

$results = get-adgroup -filter {info -like “*”} -searchbase $searchbase

foreach ( $result in $results )

{

$ArrayProcessList += $result.distinguishedname

}

$ArrayProcessList

When running in the runbook tester with an admin user all works fine. However when testing with a calling runbook so the runbook is executed on the runbook server using service acocunts I recieve an error:

clip_image002

Hmm strange.

Digging into this issue I noticed that the powershell version running using the run .net script is a V2.0 X86 powershell edition ( thank for that Thomas 🙂 )

As you can see in the default V3 version the import-module works.

clip_image004

And this doesn’t work in the V2 version :

clip_image006

Okay , so we have identified the issue , how to resolve it ?

We like this : http://karlprosser.com/coder/2012/04/16/calling-powershell-v3-from-orchestrator-2012/

Modify the script so it starts a new powershell session and pass the output

clip_image008

So start with a variable and run powershell { command} after this, make sure you output the desired result and then pass the initial variable as published data.

clip_image010

And check result !

clip_image012

clip_image014

Yes ! Success.

Enjoy.

Gino D


Quick Tip ! Redistribute failed packages in ConfigMgr #RDProud

May 26, 2015

Hello,

We were having issues with several packages not being distributed correctly in a large sccm 2012 environment. If we redsitribute the failed packages on a specific dp then the issue is resolved.

We’ll perform a root cause analysis next time, let’s focus on getting our content to the DP’s for now.

So I have created a powershell script ( based on http://www.david-obrien.net/2013/11/redistribute-failed-packages-configmgr-dps/ ) that will take all the failed distributions on a specifc DP and refresh them.

Here it is ( replace XXX with your site code):

$fileserver=”%Name_of_your_DP%”

$failures = Get-WmiObject -Namespace root\sms\site_XXX -Query “SELECT packageid FROM SMS_PackageStatusDistPointsSummarizer WHERE (State = 3 AND SourceNALPath like ‘$fileserver’ )”

foreach ( $failure in $failures )

{

$id = $failure.PackageID

write-host $id

$DP = Get-WmiObject -Namespace root\sms\site_XXX -Query “SELECT * FROM SMS_DistributionPoint WHERE (ServerNALPath like ‘$fileserver’ and PackageID=’$id’ )”

write-host $DP

$dp.RefreshNow=$true

$dp.put()

}

If you combine this with content validation on a schedule and the report ->

Software Distribution -> Content -> All active content distribution -> failed

clip_image002

You can export to csv and have a nice filtered excel that can be used as in order to select the correct DP.

clip_image004

Enjoy.

Gino D


Add a password to task sequence ConfigMgr #rdproud

May 19, 2015

 

Hello,

Say you want to add a password to a task sequence ?

Yes, you can do that starting from PXE but not starting from the OS (out-of-the-box) so let’s modify.

First create a simple posh Script ,

# Script can be used in order to ask a password in SCCM task sequence

# Requries vPassword to be created in TS , if input equals then vContinue will be set to OK

#

# Gino D’hoker

#

# 4/05/2015

$password = Read-host “Please enter the password.” -AsSecureString

# Prompt for input

$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment

If ($password -eq $tsenv.Value(“vPassword”))

{

$tsenv.Value(“vContinue”)=”OK”

}

clip_image002

This will ask for input, check if the answer is identical to a ts variable called vPassword and then set a variable called vContinue to OK.

Now let’s create the ts, you’ll need the MDT package for Serviceui.exe in order to allow interaction with the ts

clip_image004

Step 1 will only be applied if not in WinPE

clip_image006

Now use the mdt package and perform a custom action for asking input

clip_image008

Because we’ll use the same ts from PXE and from OS we’ll need to set the vContinue to OK if started from PXE

clip_image010

clip_image012

And now just continue the rest of the ts only of the vContinue is OK

clip_image014

So what does this look like ? Step 1 you receive the default warning

clip_image016

Step 2 the script asks for the password.

clip_image018

If incorrect it will not perform the reinstallation.

P.S I know the dos box isn’t state of the art, I’ll check into the Powershell forms the next time to get a more fancy request for input

The rest you know.

Enjoy.

Gino D


Quick tip ! Azure Automation

November 19, 2014

Hello,

Want to save some money on your cloud infra ? Make sure to put it off when you’re not using it.

And now you have the ability to use some automation features for this.

Compare it to orchestrator here : http://msdn.microsoft.com/en-us/library/azure/dn643629.aspx

 

Log on to the azure management portal and open automation

 


 

Create an account

 


Fill in accountname and select region

 


Ok now we can create a new runbook . You can create one from scratch or use an existing runbook.

 


In this case we want to shut down the environment.

 

You can review the script presented.

 


And modify the name, account or subscription.

 


 

Ok now go to the runbook and modify the required parameters.

Use the author command.

 


 

Test the runbook

 


 

And verify the result

 

 


 

As you can see we need to create a connection Asset. So back to to the runbooks -> Assets.

Additional information about the assets can be found here http://azure.microsoft.com/blog/2014/07/29/getting-started-with-azure-automation-automation-assets-2/


And add a setting. Make sure to copy your subscription ID before starting the wizard !


 

Select a connection, Azure, give it a name.

 


And create a cert and paste your subscription id.

 

 

Now create a self signed certificate for uploading to Azure.

Use server 2012 R2 web services.

 

Open IIS -> Server certificates

 


 

Create a self signed certificate

 


 

Modify name and leave it in personal store

 

 

 

Click view details and copy to file

 


 

Export once as cer without private key.

 


And once as .pfx with the private key.

 


 

Now add the .cer file to Azure management certificates.

 


 

Now back to Azure Automation and create an additional credential asset.

 


 

Next up browse for your .pfx file and enter your password.

 


 

 

Now go to the runbook and modify the parameters using the author tool.

 


 

$MyConnection -> This your Automation connection created in the assets section

$MyCert = This is the name of the new imported credential in the assets section

 

Also correct the Azure subscription name hardcoded in the script.

 

 


 

Save , test and verify result.


 

Haleluja ! Success !

Now all we need to do is add a schedule and that’s it.

Publish.


 

Now create a new schedule

 


Name it.

 


In this case set to Friday , 19:00 each 7 days.

 


That’s it , imagine the possibilities.

 

Enjoy.

Gino D

Additional info can be found here : http://blogs.technet.com/b/keithmayer/archive/2014/04/04/step-by-step-getting-started-with-windows-azure-automation.aspx

 



Application Approval Request Notification from Configuration Manager 2012 using Powershell

May 27, 2014

Hi all,

 

Today I was working at a customer and configuring the Application Catalog using Configuration Manager 2012 R2. The customer was interested in the application approval process but was a little disappointed that out-of-the-box it’s not possible to receive notifications when an approval request arrives in Configuration Manager.

As the customer only has Configuration Manager it’s not possible to use any other System Center product like Orchestrator or Service Manager to get things going.

I created an alternative under the form of a Powershell script that runs on a specific schedule (eg. Once every day) to gather all application requests that have a pending approval. This report is emailed to the IT mailbox of the customer. This also makes sure that an administrator doesn’t have to check every now and then in the approval request section of the Configuration Manager console to see if anything new has arrived.

What the script does is basically the following:

  • Reading all data from the WMI class SMS_UserApplicationRequest
  • Filtering all requests which have a current state of 1 ( which means requested)
  • Creating an HTML document which displays a table with all pending requests
  • Sending an email to the IT mailbox with the table as contents. The table contains per request: username, application name, comments and last modified date

The report looks as follows

Application_request_27052014_1

Anyone that might be interested in this script can comment below and I’ll be happy to help.

Cheers,

B