Category Archives: Office 365

OnedriveMapper 4.04 with auto reconnect

Version 4.04 OnedriveMapper now automatically reconnects drives (of any type) when the cookie expires. No more ‘broken’ mappings! The script is smart enough to detect if its just a connectivity issue (= do nothing) or an actual drive issue.

All improvements since 4.00:

  1. Auto Remap (automatically reconnect disconnected drives)
  2. Block the IE firstrun wizard properly
  3. Bugfix: properly handle existing shortcuts instead of throwing an error
  4. Increase Converged Drive (single mapping with sub-mappings) reliability
  5. Better cleanup of existing mappings
  6. Always force the ‘keep me signed in’ option
  7. Support for root-level mappings

OnedriveMapper 4.00 with Modern Auth released!

Modern Authentication in OnedriveMapper

With version 4.00 OnedriveMapper now fully supports ‘Modern’ Authentication!

As I wrote started this script in my early programming days and there’s a lot of crap code in there I also finally cleaned up a little, reducing the total number of lines by ~50% 🙂

The result is a much faster, leaner script that will map and/or redirect to anything in Office 365 for any of your users. MFA? Not a problem. External MFA? Also not a problem. Conditional Access? Totally fine.

Some older rarely used legacy features were removed, and login is only silent if no MFA / SSO is configured for IE.

The older version (3.X) will remain in my git repo but will not be actively maintained.

Using runbooks interactively in PowerApps (Build your own app in < 10 minutes!)

Mostly, the users of my PowerShell scripts are themselves PowerShell users. Sometimes though, the audience is less tech-savvy. In this blog post (with my first EVER video tutorial!) I’ll show you how to give your users a super user friendly interface to your scripts: Microsoft PowerApps.

You’ll need a PowerApps trial or license to follow this tutorial.

When you use the Azure AD group that was created to publish your app to when it is ready for distribution, your users will automatically be granted the correct permissions in Azure to start a runbook, as PowerApps does not use its own identity when interacting with connectors, it impersonates the user identity.

The source code for the runbook is:

Param(
    [String]$searchParameter
)

$uri = "https://techcommunity.microsoft.com/t5/forums/searchpage/tab/message?advanced=false&allow_punctuation=false&q=$searchParameter"

Start-Sleep -s 2

Write-Output "Runbook started, searching for $searchParameter..."

$res = Invoke-WebRequest -Uri $uri -UseBasicParsing -Method GET -ErrorAction Stop

Start-Sleep -s 2

Write-Output "found some results, analyzing...."

$firstHit = $res.Links | where-object {$_.outerHTML -like "*lia-link-navigation*" -and $_.href -like "/t5/*"} | select href -First 1 -ExpandProperty href
$firstHit = "https://techcommunity.microsoft.com/$firstHit"

Start-Sleep -s 2

Write-Output "Retrieving first 100 characters of first result..."

$res = Invoke-WebRequest -Uri $firstHit -UseBasicParsing -Method GET -ErrorAction Stop
$excerpt = $res.Content.Substring(($res.Content.IndexOf("class=`"lia-message-body-content`"")+64),100) -Replace('<[^>]+>','')

Start-Sleep -s 2

Write-Output "Result:"
Write-Output $excerpt
write-Output ""
write-Output ""
write-Output ""
write-Output "source: $firstHit"

The app screen’s OnStart property’s function is:

Set(runbookOutput,Blank());Set(runbookJobId,Blank());Set(runbookActive,false);Set(runbookResult,Blank())

The search button’s function is:

Set(runbookResult,Blank());Set(runbookOutput,Blank());Set(runbookJobId,Blank());Set(runbookActive,true);Set(runbookJobId,'new-searchQuery'.Run(TextInput2.Text).jobid)

The status label’s function is:

If(IsBlank(runbookResult) && runbookActive = false," ",If(runbookActive,"Please wait for job to complete…",Concatenate("Job result: ",runbookResult)))

The timer OnTimerStart function is:

If(runbookActive && Len(runbookJobId) > 5,Set(runbookOutput,'get-searchQueryOutput'.Run(runbookJobId).joboutput))

The timer OnTimerEnd function is:

If(runbookActive && Len(runbookJobId) > 5,Set(runbookResult,'get-searchQueryStatus'.Run(runbookJobId).jobstatus));If(runbookResult = "Completed" Or runbookResult = "Suspended" Or runbookResult = "Stopped",Set(runbookActive,false));