Обычно для запланированных сценариев я сохраняю файл ha sh на диск для учетных данных, которые будут использоваться сценарием следующим образом:
$Credential = Get-Credential Admin@domain.com
$Credential.Password | ConvertFrom-SecureString | Set-Content "C:\admin.pwd" $Username = "Admin@domain.com"
$Password = Get-Content "C:\admin.pwd" -ErrorAction stop | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
Следующий запрос маркера присяги работает, если элемент пароля в Тело вводится в виде простого текста, но оно не работает, если я использую переменную $ Credential.Password. Есть ли способ заставить это работать или защитить пароль иным образом?
Ошибка, которую генерирует следующий запрос токена:
Ошибка: Invoke-RestMethod: {"error": "invalid_grant "," error_description ":" AADSTS50126: Ошибка при проверке учетных данных из-за неверного имени пользователя или пароля ... "error_uri": "login.microsoftonline.com/error?code=50126"casts
## Request an access token
# Define AppId, secret and scope, your tenant name and endpoint URL
$AppId = 'AppIdHere'
$AppSecret = 'AppSecretHere'
$Scope = "https://outlook.office365.com/.default"
$TenantName = "Domain.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Create body
$Body = @{
client_id = $AppId
client_secret = $AppSecret
scope = $Scope
grant_type = 'password'
username = 'Admin@domain.com'
password = $Credential.Password
}
# Splat the parameters for Invoke-Restmethod for cleaner code
$PostSplat = @{
ContentType = 'application/x-www-form-urlencoded'
Method = 'POST'
# Create string by joining bodylist with '&'
Body = $Body
Uri = $Url
}
# Request the token for user!
$Request = Invoke-RestMethod @PostSplat
$Request.access_token
##########
== =========================
Обновлен скрипт на основе ответа от thepip3r и поддержка Microsoft :
Пароль и секрет передаются в виде простого текста на проводе, но не раскрываются в скрипте, и имеют степень безопасности, сохраняемую в виде хеш-файлов
Настраивается, чтобы не сохранять пароль или секрет в переменные для повышения безопасности от атак, которые могут получить доступ к памяти (рекомендуется поддержка MS)
Возможность использовать сертификат для зарегистрированного приложения Azure вместо секретного приложения для повышения безопасности на проводе
Альтернативным вариантом является использование "Azure Au tomation", которая позволяет запускать скрипты из O365, что должно быть намного более безопасным. Другой возможной альтернативой могут быть Azure Функции.
# One time AppID\Secret hash save to file:
## $AppCredential = Get-Credential 'AppIdHere'
## $AppCredential.Password | ConvertFrom-SecureString | Set-Content "C:\App.pwd"
# One time Admin hash save to file:
## $Credential = Get-Credential admin@domain.com
## $Credential.Password | ConvertFrom-SecureString | Set-Content "C:\admin.pwd"
$AppId = 'AppIdHere'
$AppS = Get-Content "C:\App.pwd" | ConvertTo-SecureString
$AppCredential = New-Object System.Management.Automation.PSCredential($AppId,$AppS)
$Username = "admin@domain.com"
$Password = Get-Content "C:\admin.pwd" | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential($Username,$Password)
### Request an access token ###
$Scope = "https://outlook.office365.com/.default"
$TenantName = "usablelife.onmicrosoft.com"
$Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"
# Add System.Web for urlencode
Add-Type -AssemblyName System.Web
# Request the token!
$Request = Invoke-RestMethod -Body @{
client_id = $AppId
client_secret = $AppCredential.GetNetworkCredential().Password
scope = $Scope
grant_type = 'password'
username = $Username
password = $Credential.GetNetworkCredential().Password
} `
-ContentType 'application/x-www-form-urlencoded' `
-Method 'POST' `
-Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"