Automatischer Login für OneDrive mit Benutzernamen und Passwort - Machbarkeitstest

Bild des Benutzers Marcel Meurer

Im Februar schrieb ich ein PowerShell-Modul für die PowerShellGallery. Das Modul stellt Befehle für die Interaktion mit OneDrive (https://www.sepago.com/blog/2016/02/21/Use-PowerShell-Module-OneDrive-from-PowerShellGallery-command-line) zur Verfügung. Der Befehl Get-ODAuthentication authentifiziert Benutzer auf OneDrive mit Hilfe der Microsoft Live-Website. Auf dieser gibt der Benutzer seine Anmeldeinformationen ein und wird authentifiziert. Soweit ich weiß, ist es derzeit nicht möglich, Anmeldungen über ein Skript unbeaufsichtigt durchzuführen.

In diesem Blog biete ich eine Möglichkeit, den Login automatisch durchzuführen. Aber Vorsicht: Diese Methode verwendet ein Internet Explorer-com-Objekt, um die Anmeldung durchzuführen. Der unbeaufsichtigte Login kann fehlschlagen, wenn Microsoft etwas an den Seiten ändert. Ich gehe auch davon aus, dass dieser Weg weder von Microsoft supported wird (das ist sicher) noch gewünscht ist. Ich habe diese Herausforderung zum Trainieren von PowerShell und IE Remoting genutzt. Die ist teilweise sehr gruselig (IE 11 auf Win10 und Server handeln z.B. das Eventhandling verschieden etc..).

Getestet habe ich das Skript mit den folgenden Betriebssystemen:

  • Windows 10: Englisch, Deutsch, IE11
  • Windows Server 2012 R2: Englisch, Deutsch, IE11

Das Skript funktioniert folgendermaßen:

  1. Öffnen einer einzelnen IE Instanz zum Abmelden eines evtl. angemeldeten Benutzers
  2. Navigation zur Login-Seite
  3. Ausfüllen des Formulars (Benutzername und Passwort)
  4. Senden des Change Events an die Felder
  5. Klicken zum Senden
  6. Zugriff bestätigen
  7. Das Zugriffstoken extrahieren

$DebugPreference = "Continue"

#Variables
$LoginName="Marcel.Meurer@sepago.de"
$Password="------------"
$ClientID="00000000XXXXXXXXXXXXXXX"

#Add *.live.com and *.gfx.ms to trusted sites
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains" -Name "live.com" –Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains\live.com" -Name "https" -Value 2
New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains" -Name "gfx.ms" –Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains\gfx.ms" -Name "https" -Value 2
#Enable protected mode for trusted sites
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" -Name "2500" -Value 0


$URIGetAccessToken="https://login.live.com/oauth20_authorize.srf?client_id="+$ClientID+"&scope=onedrive.readwrite&response_type=token&redirect_uri=https://login.live.com/oauth20_desktop.srf"

#Create IE Com-object
$ie = New-Object -com "InternetExplorer.Application.1" 
$ieLogout = New-Object -com "InternetExplorer.Application.1" 
$ie.visible = $false
$ie.silent = $true

write-debug ("Logout first")
$ieLogout.Navigate("https://login.live.com/logout.srf")
while($ieLogout.busy){Start-Sleep 1} 
$ieLogout.Quit()

write-debug ("Go to login page")
$ie.Navigate($URIGetAccessToken)
while($ie.busy){Start-Sleep 1} 

#Check, if function createEvent exist
$legacy=$false
try {$ie.document.createEvent()| Out-Null} catch {$legacy=$true}

if ($legacy) {write-debug ("Working in legacy mode")}

if (!$legacy) {
    #Prepare event
    $evt = $ie.document.createEvent("HTMLEvents")
    $evt.initEvent("change",$true,$false)
}

write-debug ("Filling the formular")
$ie.Document.IHTMLDocument3_getElementsByName("login").item().Value=$LoginName
$ie.Document.IHTMLDocument3_getElementsByName("loginfmt").item().Value=$LoginName
$ie.Document.IHTMLDocument3_getElementsByName("passwd").item().Value=$Password

write-debug ("Sending change events to the fields")
if ($legacy)
{
    $ie.Document.IHTMLDocument3_getElementsByName("loginfmt").item().FireEvent("onChange") | Out-Null
    $ie.Document.IHTMLDocument3_getElementsByName("passwd").item().FireEvent("onChange") | Out-Null
} else
{
    $ie.Document.IHTMLDocument3_getElementsByName("loginfmt").item().DispatchEvent($evt) | Out-Null
    $ie.Document.IHTMLDocument3_getElementsByName("passwd").item().DispatchEvent($evt) | Out-Null
}


write-debug ("Press submit")
$ie.Document.IHTMLDocument3_getElementsByName("idSIButton9").item().click()
while($ie.busy){Start-Sleep 1} 

write-debug ("Confirm access")
$ie.Document.IHTMLDocument3_getElementsByName("ucaccept").item().click()
while($ie.busy){Start-Sleep 1} 


$ReturnURI=($ie.LocationURL).ToString().Replace("#","&")

$ie.Quit()


$Authentication = New-Object PSObject
ForEach ($element in $ReturnURI.Split("?")[1].Split("&")) 
{
	$Authentication | add-member Noteproperty $element.split("=")[0] $element.split("=")[1]
}
if ($Authentication.PSobject.Properties.name -match "expires_in")
{
	$Authentication | add-member Noteproperty "expires" ([System.DateTime]::Now.AddSeconds($Authentication.expires_in))
}
if (!($Authentication.PSobject.Properties.name -match "expires_in"))
{
	write-warning("There is maybe an errror, because there is no access_token!")
}
$Authentication.scope=$Authentication.scope.Replace("%20"," ")

$Authentication

Kommentare
Firefox Web Browser
Hello, thank you for your post. But, do you have solution for Firefox Web Browser? Thanks in advance.
Bild des Benutzers Marcel Meurer
Firefox
Sorry. I have only this for the ie because the object comes with windows. Marcel
Thank you verymuch!!. You
Thank you verymuch!!. You save my life :D
Hi. I got a problem is
Hi. I got a problem is "Method invocation failed because [System.__ComObject] does not contain a method named 'IHTMLDocument3_getElementsByName'.". i has tried to run as administrator, install .Net Framwork 4.1 but can't help anything. Can u help me know what is happening? Thank you so much!!
Bild des Benutzers Marcel Meurer
Hi PwnPP4fun.
Hi PwnPP4fun. If this problem exist send me a mail: marcel.meurer (at)sepago.de and I hope we can fix it. Marcel
Neuen Kommentar schreiben
Durch Absenden dieses Formulars akzeptieren Sie die Mollom Privatsphärenrichtlinie.