question

WilliamKirby-0409 avatar image
0 Votes"
WilliamKirby-0409 asked WilliamKirby-6997 answered

Need Help to make this Script create the drives from powershell in Azure

So I found a script online that works a charm when I am connected on a VPN - I am in the process of creating an Always on VPN connection at the moment so when that happens this should be redundant to a degree, but that is a few months away and I need something now - urgently.

So I need to edit this script so that mapped network drives will be created regardless of whether the end user is connected or not to the VPN and our .local domain on Premise.

I have checked through forums and seen the following "Net Use"

"net use [{devicename | *}] [\\computername\sharename[\volume] [{password | *}]] [/user:[domainname\]username] [/user:[dotteddomainname\]username] [/user:[username@dotteddomainname] [/home {devicename | *} [{password | *}]] [/persistent:{yes | no}] [/smartcard] [/savecred] [/delete] [/help] [/?]

But I am not sure how this would fit in with the script I have for PowerShell in azure when configuring devices (Using Autopilot and Heavily Edited out to conceal domain information and generalized for posting!)



 Set-ExecutionPolicy -Scope CurrentUser -executionpolicy Bypass
    
 [CmdletBinding()]
 Param()
    
 ###########################################################################################
 # Start transcript for logging
 ###########################################################################################
    
 Start-Transcript -Path $(Join-Path $env:temp "DriveMapping.log")
    
 ###########################################################################################
 # Input values from generator
 ###########################################################################################
    
 $driveMappingJson = '[{"Path":"\\\\DN-EXAMPLE\\Production","DriveLetter":"P","Label":"Production","Id":1,"GroupFilter":"Azure_P_Drive"}]'
    
 $driveMappingConfig = $driveMappingJson | ConvertFrom-Json -ErrorAction Stop
    
 # Override with your Active Directory Domain Name e.g. 'DN-EXAMPLE' if you haven't configured the domain name as DHCP option
 $searchRoot = "DN-EXAMPLE"
    
 # If enabled all mounted PSdrives from filesystem except os drives get disconnected if not specified in drivemapping config
 $removeStaleDrives = $true
    
 ###########################################################################################
 # Helper function to determine a users group membership
 ###########################################################################################
    
 # Kudos for Tobias Renström who showed me this!
 function Get-ADGroupMembership {
     param(
         [parameter(Mandatory = $true)]
         [string]$UserPrincipalName
     )
    
     process {
    
         try {
    
             if ([string]::IsNullOrEmpty($env:USERDNSDOMAIN) -and [string]::IsNullOrEmpty($searchRoot)) {
                 Write-Error "Security group filtering won't work because `$env:USERDNSDOMAIN is not available!"
                 Write-Warning "You can override your AD Domain in the `$overrideUserDnsDomain variable"
             }
             else {
    
                 # if no domain specified fallback to PowerShell environment variable
                 if ([string]::IsNullOrEmpty($searchRoot)) {
                     $searchRoot = $env:USERDNSDOMAIN
                 }
    
                 $searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
                 $searcher.Filter = "(&(userprincipalname=$UserPrincipalName))"
                 $searcher.SearchRoot = "LDAP://$searchRoot"
                 $distinguishedName = $searcher.FindOne().Properties.distinguishedname
                 $searcher.Filter = "(member:1.2.840.113556.1.4.1941:=$distinguishedName)"
    
                 [void]$searcher.PropertiesToLoad.Add("name")
    
                 $list = [System.Collections.Generic.List[String]]@()
    
                 $results = $searcher.FindAll()
    
                 foreach ($result in $results) {
                     $resultItem = $result.Properties
                     [void]$List.add($resultItem.name)
                 }
    
                 $list
             }
         }
         catch {
             #Nothing we can do
             Write-Warning $_.Exception.Message
         }
     }
 }
    
 #check if running as system
 function Test-RunningAsSystem {
     [CmdletBinding()]
     param()
     process {
         return [bool]($(whoami -user) -match "S-1-5-18")
     }
 }
    
 ###########################################################################################
 # Get current group membership for the group filter capabilities
 ###########################################################################################
    
 Write-Output "Running as SYSTEM: $(Test-RunningAsSystem)"
    
 if ($driveMappingConfig.GroupFilter) {
     try {
         #check if running as user and not system
         if (-not (Test-RunningAsSystem)) {
    
             $groupMemberships = Get-ADGroupMembership -UserPrincipalName $(whoami -upn)
         }
     }
     catch {
         #nothing we can do
     }
 }
 ###########################################################################################
 # Mapping network drives
 ###########################################################################################
 #Get PowerShell drives and rename properties
    
 if (-not (Test-RunningAsSystem)) {
    
     $psDrives = Get-PSDrive | Where-Object { $_.Provider.Name -eq "FileSystem" -and $_.Root -notin @("$env:SystemDrive\", "D:\") } `
     | Select-Object @{N = "DriveLetter"; E = { $_.Name } }, @{N = "Path"; E = { $_.DisplayRoot } }
    
     # only map drives where group membership applicable
     $driveMappingConfig = $driveMappingConfig | Where-Object { $groupMemberships -contains $_.GroupFilter -or $_.GroupFilter -eq $null }
    
     #iterate through all network drive configuration entries
     foreach ($drive in $driveMappingConfig) {
    
         try {
             #check if variable in unc path exists, e.g. for $env:USERNAME -> resolving
             if ($drive.Path -match '\$env:') {
                 $drive.Path = $ExecutionContext.InvokeCommand.ExpandString($drive.Path)
             }
    
             #if label is null we need to set it to empty in order to avoid error
             if ($null -eq $drive.Label) {
                 $drive.Label = ""
             }
    
             $exists = $psDrives | Where-Object { $_.Path -eq $drive.Path -or $_.DriveLetter -eq $drive.DriveLetter }
             $process = $true
    
             if ($null -ne $exists -and $($exists.Path -eq $drive.Path -and $exists.DriveLetter -eq $drive.DriveLetter )) {
                 Write-Output "Drive '$($drive.DriveLetter):\' '$($drive.Path)' already exists with correct Drive Letter and Path"
                 $process = $false
    
             }
             else {
                 # Mapped with wrong config -> Delete it
                 Get-PSDrive | Where-Object { $_.DisplayRoot -eq $drive.Path -or $_.Name -eq $drive.DriveLetter } | Remove-PSDrive -EA SilentlyContinue
             }
    
             if ($process) {
                 Write-Output "Mapping network drive $($drive.Path)"
                 $null = New-PSDrive -PSProvider FileSystem -Name $drive.DriveLetter -Root $drive.Path -Description $drive.Label -Persist -Scope global -EA Stop
                 (New-Object -ComObject Shell.Application).NameSpace("$($drive.DriveLetter):").Self.Name = $drive.Label
             }
         }
         catch {
             $available = Test-Path $($drive.Path)
             if (-not $available) {
                 Write-Error "Unable to access path '$($drive.Path)' verify permissions and authentication!"
             }
             else {
                 Write-Error $_.Exception.Message
             }
         }
     }
    
     # Remove unassigned drives
     if ($removeStaleDrives -and $null -ne $psDrives) {
         $diff = Compare-Object -ReferenceObject $driveMappingConfig -DifferenceObject $psDrives -Property "DriveLetter" -PassThru | Where-Object { $_.SideIndicator -eq "=>" }
         foreach ($unassignedDrive in $diff) {
             Write-Warning "Drive '$($unassignedDrive.DriveLetter)' has not been assigned - removing it..."
             Remove-SmbMapping -LocalPath "$($unassignedDrive.DriveLetter):" -Force -UpdateProfile
         }
     }
    
     # Fix to ensure drives are mapped as persistent!
     $null = Get-ChildItem -Path HKCU:\Network -ErrorAction SilentlyContinue | ForEach-Object { New-ItemProperty -Name ConnectionType -Value 1 -Path $_.PSPath -Force -ErrorAction SilentlyContinue }
 }
    
 ###########################################################################################
 # End & finish transcript
 ###########################################################################################
    
 Stop-transcript
    
 ###########################################################################################
 # Done
 ###########################################################################################
    
 #!SCHTASKCOMESHERE!#
    
 ###########################################################################################
 # If this script is running under system (IME) scheduled task is created  (recurring)
 ###########################################################################################
    
 if (Test-RunningAsSystem) {
    
     Start-Transcript -Path $(Join-Path -Path $env:temp -ChildPath "IntuneDriveMappingScheduledTask.log")
     Write-Output "Running as System --> creating scheduled task which will run on user logon"
    
     ###########################################################################################
     # Get the current script path and content and save it to the client
     ###########################################################################################
    
     $currentScript = Get-Content -Path $($PSCommandPath)
    
     $schtaskScript = $currentScript[(0) .. ($currentScript.IndexOf("#!SCHTASKCOMESHERE!#") - 1)]
    
     $scriptSavePath = $(Join-Path -Path $env:ProgramData -ChildPath "intune-drive-mapping-generator")
    
     if (-not (Test-Path $scriptSavePath)) {
    
         New-Item -ItemType Directory -Path $scriptSavePath -Force
     }
    
     $scriptSavePathName = "DriveMappping.ps1"
    
     $scriptPath = $(Join-Path -Path $scriptSavePath -ChildPath $scriptSavePathName)
    
     $schtaskScript | Out-File -FilePath $scriptPath -Force
    
     ###########################################################################################
     # Create dummy vbscript to hide PowerShell Window popping up at logon
     ###########################################################################################
    
     $vbsDummyScript = "
     Dim shell,fso,file
    
     Set shell=CreateObject(`"WScript.Shell`")
     Set fso=CreateObject(`"Scripting.FileSystemObject`")
    
     strPath=WScript.Arguments.Item(0)
    
     If fso.FileExists(strPath) Then
         set file=fso.GetFile(strPath)
         strCMD=`"powershell -nologo -executionpolicy ByPass -command `" & Chr(34) & `"&{`" &_
         file.ShortPath & `"}`" & Chr(34)
         shell.Run strCMD,0
     End If
     "
    
     $scriptSavePathName = "IntuneDriveMapping-VBSHelper.vbs"
    
     $dummyScriptPath = $(Join-Path -Path $scriptSavePath -ChildPath $scriptSavePathName)
    
     $vbsDummyScript | Out-File -FilePath $dummyScriptPath -Force
    
     $wscriptPath = Join-Path $env:SystemRoot -ChildPath "System32\wscript.exe"
    
     ###########################################################################################
     # Register a scheduled task to run for all users and execute the script on logon
     ###########################################################################################
    
     $schtaskName = "IntuneDriveMapping"
     $schtaskDescription = "Map network drives from intune-drive-mapping-generator."
    
     $trigger = New-ScheduledTaskTrigger -AtLogOn
     #Execute task in users context
     $principal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -Id "Author"
     #call the vbscript helper and pass the PosH script as argument
     $action = New-ScheduledTaskAction -Execute $wscriptPath -Argument "`"$dummyScriptPath`" `"$scriptPath`""
     $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
    
     $null = Register-ScheduledTask -TaskName $schtaskName -Trigger $trigger -Action $action  -Principal $principal -Settings $settings -Description $schtaskDescription -Force
    
     Start-ScheduledTask -TaskName $schtaskName
    
     Stop-Transcript
 }
    
 ###########################################################################################
 # Done
 ###########################################################################################

windows-10-networkwindows-10-setup
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

CandyLuo-MSFT avatar image
0 Votes"
CandyLuo-MSFT answered

Hi ,

Based on my understanding, you want to use net use command to create mapped network drives regardless of whether the end user is connected or not connect to the VPN. Is that right? Please feel free to let me know if I have any misunderstanding.

If we want to map network drive, we need first ensure network connection is fine:

119011-1.png

If you disconnect and there is no network connection between your VPN client and file server, then net use command will not work:

119012-2.png

So we must confirm network connection is fine and then we can map network drive.

Best Regards,
Candy


If the Answer is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



1.png (38.5 KiB)
2.png (36.4 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

WilliamKirby-6997 avatar image
0 Votes"
WilliamKirby-6997 answered

That doesn't really help too much, as the user won't be connected to the VPN when the drive mapping script (in powershell scripting via intune) runs.

I might have to approach this differently

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.