Skip to content

Commit

Permalink
Implemented recurring functionality for client side script, code opti…
Browse files Browse the repository at this point in the history
…mization.
  • Loading branch information
nicolonsky committed Jul 28, 2019
1 parent 84f8734 commit 4d5ef8a
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 38 deletions.
6 changes: 4 additions & 2 deletions IntuneDriveMapping/Views/DriveMapping/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
@{
ViewData["Title"] = "intune-drive-mapping generator-";
}
<script src="~/vendor.min.js"></script>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<code class="float-right">Version: @ViewBag.Version</code>

<h2>intune-drive-mapping-generator</h2>

@using (Html.BeginForm("Upload", "DriveMapping", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
if (ViewBag.ShowList != true)
Expand Down Expand Up @@ -149,5 +151,5 @@
}
}

<code class="float-right mt-5 pt-2">Version: @ViewBag.Version</code>


180 changes: 144 additions & 36 deletions IntuneDriveMapping/wwwroot/bin/IntuneDriveMappingTemplate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,40 @@ $driveMappingConfig= $driveMappingJson | ConvertFrom-Json

# Kudos for Tobias Renström who showed me this!
function Get-ADGroupMembership {
param(
[parameter(Mandatory=$true)]
[string]$UserPrincipalName
)
param(
[parameter(Mandatory=$true)]
[string]$UserPrincipalName
)
process{

try{

$Searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$Searcher.Filter = "(&(userprincipalname=$UserPrincipalName))"
$Searcher.SearchRoot = "LDAP://$env:USERDNSDOMAIN"

$Searcher.FindOne().GetDirectoryEntry().memberOf | ForEach-Object {

$PSItem.split(",")[0].replace("CN=","")
$Searcher.SearchScope = "subtree"

$distinguishedname = $Searcher.FindOne().Properties.distinguishedname

$GroupFilter = "(member:1.2.840.113556.1.4.1941:=$distinguishedname)"
$Searcher.Filter = $GroupFilter
$Searcher.SearchScope = "Subtree"

[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{

Write-Warning "Could not determine group membership for: $UserPrincipalName"
#Nothing we can do
Write-Warning $_.Exception.Message
}
}
}
Expand All @@ -56,60 +71,67 @@ function Get-ADGroupMembership {
###########################################################################################

if ($driveMappingConfig.GroupFilter){
try{
#check if running as user and not system
if (-not ($(whoami -user) -match "S-1-5-18")){

$groupMemberships = Get-ADGroupMembership -UserPrincipalName $(whoami -upn)
$groupMemberships = Get-ADGroupMembership -UserPrincipalName $(whoami -upn)
}
}catch{
#nothing we can do
}
}

###########################################################################################
# Mapping network drives #
###########################################################################################
#Get PowerShell drives and rename properties
$psDrives = Get-PSDrive | Select-Object @{N="DriveLetter"; E={$_.Name}}, @{N="Path"; E={$_.DisplayRoot}}
try{

$psDrives = Get-PSDrive | Select-Object @{N="DriveLetter"; E={$_.Name}}, @{N="Path"; E={$_.DisplayRoot}}

}catch{

Write-Warning $_.Exception.Message
}

#iterate through all network drive configuration entries
$driveMappingConfig.GetEnumerator() | ForEach-Object {

#check if the drive is already connected with an identical configuration
if ( -not ($psDrives.Path -contains $PSItem.Path -and $psDrives.DriveLetter -contains $PSItem.DriveLetter)){
try{

#check if the drive is already connected with an identical configuration
if ( -not ($psDrives.Path -contains $PSItem.Path -and $psDrives.DriveLetter -contains $PSItem.DriveLetter)){

try{
#check if drive exists - but with wrong config - to delete it
if($psDrives.Path -contains $PSItem.Path -or $psDrives.DriveLetter -contains $PSItem.DriveLetter){

Get-PSDrive | Where-Object {$_.DisplayRoot -eq $PSItem.Path -or $_.Name -eq $PSItem.DriveLetter} | Remove-PSDrive -ErrorAction SilentlyContinue
}

## check itemleveltargeting for group membership
## check itemleveltargeting for group membership
if ($PSItem.GroupFilter -ne $null -and $groupMemberships -contains $PSItem.GroupFilter){

Write-Output "Mapping network drive $($PSItem.Path)"

$null = New-PSDrive -PSProvider FileSystem -Name $PSItem.DriveLetter -Root $PSItem.Path -Description $PSItem.Label -Persist -Scope global -ErrorAction Stop
$null = New-PSDrive -PSProvider FileSystem -Name $PSItem.DriveLetter -Root $PSItem.Path -Description $PSItem.Label -Persist -Scope global -EA SilentlyContinue

(New-Object -ComObject Shell.Application).NameSpace("$($PSItem.DriveLetter):").Self.Name=$PSItem.Label

}elseif ($PSItem.GroupFilter -eq $null) {

Write-Output "Mapping network drive $($PSItem.Path)"

$null = New-PSDrive -PSProvider FileSystem -Name $PSItem.DriveLetter -Root $PSItem.Path -Description $PSItem.Label -Persist -Scope global -ErrorAction Stop
$null = New-PSDrive -PSProvider FileSystem -Name $PSItem.DriveLetter -Root $PSItem.Path -Description $PSItem.Label -Persist -Scope global -EA SilentlyContinue

(New-Object -ComObject Shell.Application).NameSpace("$($PSItem.DriveLetter):").Self.Name=$PSItem.Label
}
}catch{

Write-Error $_.Exception

#as soon as we write to the error stream IME considers this script as failed and will try it three times more

#reset IME script execution?
#copy script to client and try to rerun it from there until success?
#package script inside win32app and detect drives via psdetectionscript
#still lookin for the best solution
}
}else{

Write-Output "Drive already exists with same DriveLetter and Path"
}

}else{

Write-Output "Drive already exists with same DriveLetter and Path"
}catch{

Write-Warning $_.Exception.Message
}
}
###########################################################################################
Expand All @@ -118,6 +140,92 @@ $driveMappingConfig.GetEnumerator() | ForEach-Object {

Stop-transcript

###########################################################################################
# Done #
###########################################################################################

#!SCHTASKCOMESHERE!#

###########################################################################################
# If this script is running under system (IME) scheduled task is created (recurring) #
###########################################################################################

Start-Transcript -Path $(Join-Path -Path $env:temp -ChildPath "IntuneDriveMappingScheduledTask.log")

if ($(whoami -user) -match "S-1-5-18"){

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 #
###########################################################################################

0 comments on commit 4d5ef8a

Please sign in to comment.