{"id":2849,"date":"2019-02-06T12:49:03","date_gmt":"2019-02-06T10:49:03","guid":{"rendered":"http:\/\/blog.hosebei.ch\/?p=2849"},"modified":"2019-02-06T12:49:03","modified_gmt":"2019-02-06T10:49:03","slug":"intune-deploy-required-user-settings-to-windows-10-with-powershell","status":"publish","type":"post","link":"https:\/\/blog.hosebei.ch\/?p=2849","title":{"rendered":"Intune &#8211; Deploy required user settings to Windows 10 with powershell"},"content":{"rendered":"<p>In this blog I would like to describe, how I managed to set required user settings to Windows 10.<br \/>\nSince I still do have an On-Premises environment, in which also File Servers reside and a DFS Namespace is still up and running, I wanted to make sure to get the advantages of using the local network.<br \/>\nSo here are my two use-cases to solve:<br \/>\n1. Add a Network location for the DFS Path if the user is logged on On-Premises<br \/>\n2. Modify the local &#8220;host&#8221; file, to redirect the workfolder clients to the file server internally<br \/>\n<!--more--><\/p>\n<p>With this goals to achieve given, it was quite clear: It&#8217;s scripting time again *happy*<br \/>\nSo I decided to create a single script, which I can use for both tasks. This means I need to check, if a user is running the script, or if it&#8217;s in System context. Due to the fact that the DFS link resides within the user profile, the script needs to run in user context. On the other hand the host file requires Admin permission for modifications. This is great, because within Intune, we can easily select, if the script should run in user or system context:<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01.png?w=300\" alt=\"\" width=\"300\" height=\"116\" class=\"aligncenter size-medium wp-image-2850\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01.png 1771w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01-300x116.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01-1024x395.png 1024w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01-768x297.png 768w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings01-1536x593.png 1536w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nMy solution to check if the script is running in system or in user context is the following line (I will provide the whole script at the end):<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings02.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings02.png\" alt=\"\" width=\"700\" height=\"49\" class=\"aligncenter size-full wp-image-2852\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings02.png 927w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings02-300x21.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings02-768x54.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>And the second important question is: Am I on the local network? For this, I simply check if I can reach port 389 of a known Domain Controller in my network:<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03.png?w=700\" alt=\"\" width=\"700\" height=\"129\" class=\"aligncenter size-large wp-image-2855\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03.png 1733w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03-300x55.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03-1024x188.png 1024w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03-768x141.png 768w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings03-1536x283.png 1536w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>With that is set, I was able to go ahead and define the settings that should get applied.<br \/>\nThe first setting was creating a Network Location within Windows explorer if the domain controller is reachable, and if the DC is not reachable to remove the Link. For the creation of the Network location, I found a very nice function of Tom White on the TechNet Gallery:<br \/>\n<a href=\"https:\/\/gallery.technet.microsoft.com\/scriptcenter\/Add-NetworkLocation-734ab70a\" rel=\"noopener\" target=\"_blank\">Add-NetworkLocation &#8211; A function to create an advanced network location<\/a><\/p>\n<p>Im simply took this function and implemented it in my script.<br \/>\nThe following section creates the link if a DC is available, or it deletes the link:<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04.png?w=700\" alt=\"\" width=\"700\" height=\"169\" class=\"aligncenter size-large wp-image-2857\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04.png 2336w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04-300x72.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04-1024x247.png 1024w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04-768x185.png 768w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04-1536x370.png 1536w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings04-2048x494.png 2048w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>This will cover the user settings. Now it&#8217;s up to the Host file. For modifying the host file, I have to make sure that the script is running in System Context, as it requires Administrative permission.<br \/>\nFor adding or removing lines to the host file, I&#8217;m using those two functions (be aware, the search string is hard-coded):<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05.png?w=700\" alt=\"\" width=\"700\" height=\"185\" class=\"aligncenter size-large wp-image-2859\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05.png 1552w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05-300x79.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05-1024x271.png 1024w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05-768x203.png 768w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings05-1536x407.png 1536w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>So I then need only to trigger the correct function:<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings06.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings06.png\" alt=\"\" width=\"700\" height=\"238\" class=\"aligncenter size-full wp-image-2860\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings06.png 931w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings06-300x102.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings06-768x261.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>All is done for the script (again, for better readability of the blog, I post the whole script at the end), and I can go ahead, and test the solution through Intune. Just create a PowerShell configuration twice with the same script, where you configure one script running in user context, and the other in system context. I created a Azure AD security group and added my test machine to the group, this group I then used for both PowerShell Configuration Profiles.<\/p>\n<p>And everything worked great:<br \/>\n<a href=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07.png?w=700\" alt=\"\" width=\"700\" height=\"228\" class=\"aligncenter size-large wp-image-2863\" srcset=\"https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07.png 2155w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07-300x98.png 300w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07-1024x334.png 1024w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07-768x250.png 768w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07-1536x500.png 1536w, https:\/\/blog.hosebei.ch\/wp-content\/uploads\/2019\/02\/intune_windows10settings07-2048x667.png 2048w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>So the first step of creating a script which does the job is done. Next up would be to deploy the script to the clients, because the Intune configuration would only run the script once. I&#8217;m thinking about to create a Script, which creates two scheduled tasks, one for the user and one for the system. The scheduled tasks would then be configured to run at user logon. But I am not sure about this yet, but I&#8217;m quite sure that I will create a blog about the final solution.<\/p>\n<p>And here is the whole script:<br \/>\n<code>Function Check-DCAvailable {<br \/>\n    param(<br \/>\n        [Parameter(Position=0,mandatory=$true)][string]$DCToCheck<br \/>\n    )<br \/>\n    #Check if DC is available on LDAP<br \/>\n    $LDAPTestResult = $null<br \/>\n    $LDAPTestResult = Test-NetConnection -ComputerName $LocalDomainController -Port 389 -ErrorAction SilentlyContinue -WarningAction SilentlyContinue<br \/>\n    if($LDAPTestResult.TcpTestSucceeded -ne $true) {<br \/>\n        Write-Host (\"Domaincontroller was not answering: \" + $LocalDomainController) -ForegroundColor Yellow<br \/>\n        return $false<br \/>\n    }<br \/>\n    else {<br \/>\n        return $true<br \/>\n    }<br \/>\n}<\/p>\n<p>function Remove-HostFileWorkFolderEntry {<br \/>\n    $hostFile = ($env:SystemRoot + \"\\System32\\drivers\\etc\\hosts\")<br \/>\n    $hostFileContent = Get-Content -Path $hostFile<br \/>\n    $hostFileContent = $hostFileContent | foreach{if(($_ -like \"*workfolders.hosebei.ch*\") -eq $true) { Write-Host $_ } else {$_}}<br \/>\n    $hostFileContent | Out-File $hostFile -enc ascii<\/p>\n<p>}<\/p>\n<p>function Add-HostFileWorkFolderEntry {<br \/>\n    $hostFile = ($env:SystemRoot + \"\\System32\\drivers\\etc\\hosts\")<br \/>\n    $hostFileContent = Get-Content -Path $hostFile<br \/>\n    if(($hostFileContent -contains \"workfolders.hosebei.ch\") -ne $true) {<br \/>\n        $hostFileContent = $hostFileContent + \"192.168.1.166\t\tworkfolders.hosebei.ch\"<\/p>\n<p>    }<br \/>\n    $hostFileContent | Out-File $hostFile -enc ascii<\/p>\n<p>}<\/p>\n<p>function Add-NetworkLocation<\/p>\n<p>{<br \/>\n    [CmdLetBinding()]<br \/>\n    param<br \/>\n    (<br \/>\n        [Parameter(Mandatory=$true)][string]$networkLocationPath,<br \/>\n        [Parameter(Mandatory=$true)][string]$networkLocationName ,<br \/>\n        [Parameter(Mandatory=$true)][string]$networkLocationTarget<br \/>\n    )<br \/>\n    Begin<br \/>\n    {<br \/>\n        Write-Verbose -Message \"Network location path: `\"$networkLocationPath`\".\"<br \/>\n        Write-Verbose -Message \"Network location name: `\"$networkLocationName`\".\"<br \/>\n        Write-Verbose -Message \"Network location target: `\"$networkLocationTarget`\".\"<br \/>\n        Set-Variable -Name desktopIniContent -Option ReadOnly -value ([string]\"[.ShellClassInfo]`r`nCLSID2={0AFACED1-E828-11D1-9187-B532F1E9575D}`r`nFlags=2\")<br \/>\n    }<br \/>\n    Process<br \/>\n    {<br \/>\n        Write-Verbose -Message \"Checking that `\"$networkLocationPath`\" is a valid directory...\"<br \/>\n        if(Test-Path -Path $networkLocationPath -PathType Container)<br \/>\n        {<br \/>\n            try<br \/>\n            {<br \/>\n                Write-Verbose -Message \"Creating `\"$networkLocationPath\\$networkLocationName`\".\"<br \/>\n                [void]$(New-Item -Path \"$networkLocationPath\\$networkLocationName\" -ItemType Directory -ErrorAction Stop)<br \/>\n                Write-Verbose -Message \"Setting system attribute on `\"$networkLocationPath\\$networkLocationName`\".\"<br \/>\n                Set-ItemProperty -Path \"$networkLocationPath\\$networkLocationName\" -Name Attributes -Value ([System.IO.FileAttributes]::System) -ErrorAction Stop<br \/>\n            }<br \/>\n            catch [Exception]<br \/>\n            {<br \/>\n                Write-Error -Message \"Cannot create or set attributes on `\"$networkLocationPath\\$networkLocationName`\". Check your access and\/or permissions.\"<br \/>\n                return $false<br \/>\n            }<br \/>\n        }<br \/>\n        else<br \/>\n        {<br \/>\n            Write-Error -Message \"`\"$networkLocationPath`\" is not a valid directory path.\"<br \/>\n            return $false<br \/>\n        }<br \/>\n        try<br \/>\n        {<br \/>\n            Write-Verbose -Message \"Creating `\"$networkLocationPath\\$networkLocationName\\desktop.ini`\".\"<br \/>\n            [object]$desktopIni = New-Item -Path \"$networkLocationPath\\$networkLocationName\\desktop.ini\" -ItemType File<br \/>\n            Write-Verbose -Message \"Writing to `\"$($desktopIni.FullName)`\".\"<br \/>\n            Add-Content -Path $desktopIni.FullName -Value $desktopIniContent<br \/>\n        }<br \/>\n        catch [Exception]<br \/>\n        {<br \/>\n            Write-Error -Message \"Error while creating or writing to `\"$networkLocationPath\\$networkLocationName\\desktop.ini`\". Check your access and\/or permissions.\"<br \/>\n            return $false<br \/>\n        }<br \/>\n        try<br \/>\n        {<br \/>\n            $WshShell = New-Object -ComObject WScript.Shell<br \/>\n            Write-Verbose -Message \"Creating shortcut to `\"$networkLocationTarget`\" at `\"$networkLocationPath\\$networkLocationName\\target.lnk`\".\"<br \/>\n            $Shortcut = $WshShell.CreateShortcut(\"$networkLocationPath\\$networkLocationName\\target.lnk\")<br \/>\n            $Shortcut.TargetPath = $networkLocationTarget<br \/>\n            $Shortcut.Description = \"Created $(Get-Date -Format s) by $($MyInvocation.MyCommand).\"<br \/>\n            $Shortcut.Save()<br \/>\n        }<br \/>\n        catch [Exception]<br \/>\n        {<br \/>\n            Write-Error -Message \"Error while creating shortcut @ `\"$networkLocationPath\\$networkLocationName\\target.lnk`\". Check your access and permissions.\"<br \/>\n            return $false<br \/>\n        }<br \/>\n        return $true<br \/>\n    }<br \/>\n}<\/p>\n<p>#-----------------------------<br \/>\n#Main Script<br \/>\n#Variables<br \/>\n$LocalDomainController = \"hosebeidc02.deheim.hosebei.ch\"<\/p>\n<p>#Determine if Script was started with system<br \/>\n$bSystemContext = ([Security.Principal.WindowsIdentity]::GetCurrent()).IsSystem<\/p>\n<p>if($bSystemContext -eq $false) {<br \/>\n    #Execute User Section<\/p>\n<p>    #Create Network Links<br \/>\n    if(Check-DCAvailable($LocalDomainController)) {<br \/>\n        #DC was found, we can assume getting a kerberos ticket for accesing SMB shares<br \/>\n        Write-Host (\"Connecting network locations\") -ForegroundColor Green<\/p>\n<p>        #test if Hosebei DFSlink is existent, if not, create it<br \/>\n        Write-Host (\"Connecting Hosebei DFS\") -ForegroundColor Green<br \/>\n        if((Test-Path -Path \"$env:APPDATA\\Microsoft\\Windows\\Network Shortcuts\\Hosebei DFS\") -ne $true) {<br \/>\n            $null = Add-NetworkLocation -networkLocationPath \"$env:APPDATA\\Microsoft\\Windows\\Network Shortcuts\" -networkLocationName \"Hosebei DFS\" -networkLocationTarget \"\\\\deheim.hosebei.ch\\hosebeiDFSroot\"<br \/>\n        }<br \/>\n    }<br \/>\n    else {<br \/>\n        #Remove existing Links<br \/>\n        Write-Host (\"Removing network locations\") -ForegroundColor Yellow<\/p>\n<p>        #test if Hosebei DFSlink is existent, if true, remove it<br \/>\n        Write-Host (\"Remove Hosebei DFS Link due to no DC Access\") -ForegroundColor Yellow<br \/>\n        if((Test-Path -Path \"$env:APPDATA\\Microsoft\\Windows\\Network Shortcuts\\Hosebei DFS\") -eq $true) {<br \/>\n            Remove-Item -Path \"$env:APPDATA\\Microsoft\\Windows\\Network Shortcuts\\Hosebei DFS\" -Force -Recurse<br \/>\n        }<br \/>\n    }<br \/>\n}<br \/>\nelse {<br \/>\n    #execute system Section<\/p>\n<p>    #Modify host file for Workfolder access<br \/>\n    #Get HostFile<br \/>\n    $hostFile = ($env:SystemRoot + \"\\System32\\drivers\\etc\\hosts\")<br \/>\n    $hostFileContent = Get-Content -Path $hostFile<br \/>\n    if(Check-DCAvailable($LocalDomainController)) {<br \/>\n        #DC was found, we can directly access the file server<br \/>\n        Add-HostFileWorkFolderEntry<br \/>\n    }<br \/>\n    else {<br \/>\n        #No DC was found, we need to sync workfolders through the azure ad app proxy<br \/>\n        Remove-HostFileWorkFolderEntry<br \/>\n    }<br \/>\n}<br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog I would like to describe, how I managed to set required user settings to Windows 10. Since I still do have an On-Premises environment, in which also File Servers reside and a DFS Namespace is still up and running, I wanted to make sure to get the advantages of using the local [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,7,12,17,19,22,24,27,29,32,43],"tags":[],"class_list":["post-2849","post","type-post","status-publish","format-standard","hentry","category-application-management","category-azure-ad","category-client-settings","category-emm","category-general","category-intune","category-mdm","category-operating-system-deployment","category-powershell","category-remote-workplace","category-windows-10"],"_links":{"self":[{"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=\/wp\/v2\/posts\/2849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2849"}],"version-history":[{"count":0,"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=\/wp\/v2\/posts\/2849\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.hosebei.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}