Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell、EWS、OAuth2和自动化_Powershell_Exchange Basicauth - Fatal编程技术网

Powershell、EWS、OAuth2和自动化

Powershell、EWS、OAuth2和自动化,powershell,exchange-basicauth,Powershell,Exchange Basicauth,我试图找到关于如何使用PowerShell对EWS实现非交互式Oauth2身份验证的文档,但我可能没有使用正确的搜索词,因为我找不到任何有用的东西。我可以在OAuth2上找到的Microsoft文档只有C#文档 那么,有人知道如何实现这一点吗 无用户输入,应使用可作为脚本输入提供的输入 应该在PowerShell中,而不是C中# 细节!细节!不是“现在生成登录令牌”,而是生成该令牌的实际代码 下面的博客对这一点有很好的概述: 我使用上面的博客让它在我们的PowerShell脚本中工作——经过

我试图找到关于如何使用PowerShell对EWS实现非交互式Oauth2身份验证的文档,但我可能没有使用正确的搜索词,因为我找不到任何有用的东西。我可以在OAuth2上找到的Microsoft文档只有C#文档

那么,有人知道如何实现这一点吗

  • 无用户输入,应使用可作为脚本输入提供的输入
  • 应该在PowerShell中,而不是C中#
  • 细节!细节!不是“现在生成登录令牌”,而是生成该令牌的实际代码

    • 下面的博客对这一点有很好的概述:

      我使用上面的博客让它在我们的PowerShell脚本中工作——经过了大量的尝试和错误。以下示例脚本使用在Azure AD中注册的应用程序的ClientID。如果尚未在Azure AD中注册应用程序,则必须首先执行此操作。web上有各种指南可用于在Azure AD中注册新应用程序。为了在OAuth中使用EWS,您注册的应用程序必须在Azure AD中具有正确的权限。EWS有两个选项:

    • 使用委派权限并请求Azure AD中的“EWS.AccessAsUser.All”API权限-旧版API | Exchange |委派权限| EWS.AccessAsUser.All(通过Exchange Web服务以登录用户身份访问邮箱)。此权限使注册的应用程序具有与登录用户相同的Exchange邮箱访问权限。如果使用此权限,则任何服务或用户帐户首次使用应用程序的ClientID访问Exchange Online时,相关帐户必须通过交互式弹出通知批准ClientID。因此,在以自动方式使用此脚本之前,您必须使用已注册应用程序的ClientID以交互方式访问Exchange Online服务,并批准授权弹出窗口。最简单的方法是使用Microsoft的免费“EWS编辑器”应用程序登录邮箱,并指定应用程序的ClientID。一旦您的应用程序的ClientID获得批准,您的脚本就可以完全自动运行,而无需任何交互
    • 使用应用程序权限并在Azure AD-旧版API | Exchange |委派权限| EWS.AccessAsUser.All中请求“完全访问”和“作为应用程序”API权限(通过Exchange Web服务以登录用户身份访问邮箱)。此权限允许您注册的应用程序通过Exchange Web服务完全访问所有邮箱,而无需登录用户。此类型的权限使应用程序能够完全访问Exchange Online服务中的任何邮箱,并且必须得到Azure AD全局管理员的批准,并提供“管理员同意”。然后,您的脚本将使用注册的Azure AD应用程序客户端ID(有效的用户名)和客户端密码(有效的密码)对Exchange Online进行身份验证
    • 下面的示例使用选项1。我还没有测试选项2。无论您选择哪个选项,您都需要处理从Azure AD请求OAuth令牌(下面代码中的示例),并定期检查和刷新令牌(无示例)。我没有这样做,因为我们所有的EWS脚本都是简单、快速运行的脚本,在需要刷新令牌之前完成(通常在60分钟内)。如果这是你需要的东西,你需要向别人寻求帮助。希望这至少能帮助你走上正轨

      下面是示例脚本(脚本主体调用“Get-EWSouthToken”函数):

      #变量
      $UserPrincipalName=“输入服务帐户ID的UPN”
      $Password=“您的服务帐户ID的密码-安全地存储此密码”
      $clientifromazuread=“Azure AD中注册应用程序的客户端ID”
      $errRecip=“发生错误时通过电子邮件通知的收件人的电子邮件地址”
      $script=“脚本名称”
      $sender=“发件人的电子邮件地址-通常是脚本运行的服务器名称”
      $logfile=“日志文件的路径和文件名”
      $smtpServer=“您的SMTP服务器”
      函数Get-ewsouthToken
      {
      [CmdletBinding()]
      Param
      (
      [System.String]$UserPrincipalName,
      [System.Security.SecureString]$Password,
      [System.String]$ADALPath,
      [System.String]$ClientId=“1234444547676878787”,
      [System.Uri]$ConnectionUri=”https://outlook.office365.com/EWS/Exchange.asmx",
      [System.Uri]$RedirectUri=”https://dummyredirectdomain.com"
      )
      开始
      {
      写入主机“正在启动从凭据函数获取EWSOuthTokenFromCredential…”-ForegroundColor黄色
      #根据Azure AD模块安装路径确定ADAL位置
      If([System.String]::IsNullOrEmpty($ADALPath))
      {
      写入主机“正在尝试定位ADAL库…”-ForegroundColor黄色
      $ADALPath=(Get InstalledModule-名称“AzureAD”-ErrorAction SilentlyContinue |选择对象InstalledLocation)。InstalledLocation
      $ADALPath=Join Path-Path$ADALPath-ChildPath“Microsoft.IdentityModel.Clients.ActiveDirectory.dll”
      写入主机“定位库@'$ADALPath'”-前底色黄色
      If([System.String]::IsNullOrEmpty($ADALPath))
      {
      #获取已安装模块的列表并检查Azure AD DLL是否可用
      $tmpMods=Get Module-ListAvailable | Where Object{$\u.Name-eq“AzureAD”}
      如果($tmpMods)
      {
      $ADALPath=拆分路径$tmpMods.Path
      $ADALPath=Join Path-Path$ADALPath-ChildPath“Microsoft.IdentityModel.Clients.ActiveDirectory.dll”
      写入主机“定位库@'$ADALPath'”-前底色黄色
      }
      其他的
      {
      $err=“$($myinvocation.mycommand.name)需要ADAL库DLL文件('Microsoft.IdentityModel.Clients.ActiveDirectory.DLL')
      
      #Variables
      $UserPrincipalName = "Enter the UPN of your Service Account ID"
      $Password = "Password of your Service Account ID - store this securely"
      $ClientIDfromAzureAD = "Client ID of your registered application in Azure AD"
      $errRecip = "Email address of recipients to notify via email if errors occur"
      $script = "Name of script"
      $sender = "Email address of sender - normally the server name where your script runs"
      $logfile = "Path and filename to log file"
      $smtpServer = "Your SMTP server"
      
      Function Get-EWSOAuthToken
      {
          <#
              .SYNOPSIS
                  Request an OAuth EWS token from Azure AD using supplied Username and Password
      
              .DESCRIPTION
                  Request an OAuth EWS token from Azure AD using supplied Username and Password
      
              .PARAMETER UserPrincipalName
                  The UPN of the user that will authenticate to Azure AD to request the OAuth Token
      
              .PARAMETER Password
                  The Password (SecureString) of the user that will authenticate to Azure AD to request the OAuth Token
      
              .PARAMETER ADALPath
                  The full path and filename on the local file system to the ADAL (Active Directory Authentication Library) DLL. This library is installed as part of various modules such as Azure AD, Exchange Online, etc.
      
              .PARAMETER ClientId
                  Identifier of the client application that is requesting the token. You must register your calling application in Azure AD. This will provide you with a ClientID and RedirectURI
      
              .PARAMETER ConnectionUri
                  The URI of the Exchange Online EWS endpoint. Default URI of 'https://outlook.office365.com/EWS/Exchange.asmx' is used
      
              .PARAMETER RedirectUri
                  Address to return to upon receiving a response from the authority. You must register your calling application in Azure AD. This will provide you with a ClientID and RedirectURI
      
              .EXAMPLE
                  $token = Get-EWSOAuthtokenFromCredential -UserPrincipalName "ABC123@mydomain.com" -Password $mySecurePassword -ClientId "123444454545454767687878787" -RedirectUri "https://dummyredirectdomain.com"
                  $ews = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2013_SP1 -ErrorAction Stop
                  $ews.UseDefaultCredentials = $False
                  $ews.Credentials = [Microsoft.Exchange.WebServices.Data.OAuthCredentials]$token
          #>
      
          [CmdletBinding()]
          Param
          (
              [System.String]$UserPrincipalName,
              [System.Security.SecureString]$Password,
              [System.String]$ADALPath,
              [System.String]$ClientId = "123444454545454767687878787",
              [System.Uri]$ConnectionUri = "https://outlook.office365.com/EWS/Exchange.asmx",
              [System.Uri]$RedirectUri = "https://dummyredirectdomain.com"
          )
      
          Begin
          {
              Write-Host "Starting Get-EWSOAuthTokenFromCredential function..." -ForegroundColor Yellow
              #Determine ADAL location based on Azure AD module installation path
              If([System.String]::IsNullOrEmpty($ADALPath)) 
              {
                  Write-Host "Attempting to locate ADAL library..." -ForegroundColor Yellow
      
                  $ADALPath = (Get-InstalledModule -Name "AzureAD" -ErrorAction SilentlyContinue | Select-Object InstalledLocation).InstalledLocation
                  $ADALPath = Join-Path -Path $ADALPath -ChildPath "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
                  Write-Host "Located library @ '$ADALPath'" -ForegroundColor Yellow
                  If([System.String]::IsNullOrEmpty($ADALPath))
                  {
                      #Get List of installed modules and check Azure AD DLL is available
                      $tmpMods = Get-Module -ListAvailable | Where-Object {$_.Name -eq "AzureAD"}
      
                      If($tmpMods)
                      {
                          $ADALPath = Split-Path $tmpMods.Path
                          $ADALPath = Join-Path -Path $ADALPath -ChildPath "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
                          Write-Host "Located library @ '$ADALPath'" -ForegroundColor Yellow
                      }
                      Else
                      {
                          $err = "$($myinvocation.mycommand.name) requires the ADAL Library DLL files ('Microsoft.IdentityModel.Clients.ActiveDirectory.dll') that are installed as part of the 'AzureAD' module! Please install the AzureAD module from the Powershell Gallery. See: 'https://www.powershellgallery.com/packages/AzureAD' for more information"
                          Throw "$err"
                      }
                  }
              }
      
              #Load 'Microsoft.IdentityModel.Clients.ActiveDirectory' DLL
              Try
              {
                  Import-Module $ADALPath -DisableNameChecking -Force -ErrorAction Stop
                  Write-Host "Successfully imported ADAL Library" -ForegroundColor Yellow
              }
              Catch
              {
                  $err = "$($myinvocation.mycommand.name): Could not load ADAL Library DLL '$ADALPath'. Error: $_"
                  Throw "$err"
              }
          }
          Process
          {
              try
                  {
                  $resource = $connectionUri.Scheme + [System.Uri]::SchemeDelimiter + $connectionUri.Host
                  $azureADAuthorizationEndpointUri = "https://login.windows.net/common/oauth2/authorize/"
                  $AuthContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext($azureADAuthorizationEndpointUri) -ErrorAction Stop
                  $AuthCredential = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential($UserPrincipalName, $Password) -ErrorAction Stop
                  Write-Host "$($myinvocation.mycommand.name): Requesting a new OAuth Token..." -ForegroundColor Yellow
                  $authenticationResult = ([Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($AuthContext, $resource, $clientId, $AuthCredential))
      
                  If ($authenticationResult.Status.ToString() -ne "Faulted") {
                      Write-Host "$($myinvocation.mycommand.name): Successfully retrieved OAuth Token" -ForegroundColor Yellow
                  }
                  else {
                      $err = "$($myinvocation.mycommand.name): Error occurred calling ADAL 'AcquireTokenAysnc' : $authenticationResult.Exception.ToString()"
                      Throw "$err"
                  }
              }
              catch
              {
                  #create object
                  $returnValue = New-Object -TypeName PSObject
      
                  #get all properties from last error
                  $ErrorProperties =$Error[0] | Get-Member -MemberType Property
      
                  #add existing properties to object
                  foreach ($Property in $ErrorProperties)
                  {
                      if ($Property.Name -eq 'InvocationInfo')
                      {
                          $returnValue | Add-Member -Type NoteProperty -Name 'InvocationInfo' -Value $($Error[0].InvocationInfo.PositionMessage)
                      }
                      else
                      {
                          $returnValue | Add-Member -Type NoteProperty -Name $($Property.Name) -Value $($Error[0].$($Property.Name))
                      }
                  }
                  #return object
                  $returnValue
                  break
              }
          }
          End
          {
              return $authenticationResult
          }
      }
      
      
      ###### Main script
      
      #Ensure TLS 1.2 protocol is enabled
      try {
          If ([Net.ServicePointManager]::SecurityProtocol -notmatch 'Tls12') {
              [Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12
              Write-Host "Enabled Tls1.2 in '[Net.ServicePointManager]::SecurityProtocol'" -ForegroundColor Yellow
          }
          else {
              Write-Host "Tls1.2 is enabled in '[Net.ServicePointManager]::SecurityProtocol'" -ForegroundColor Yellow
          }
      }
      Catch {
          $err = "An error occurred enabling TLS1.2. Error: $_"
          Write-Host "`n$err" -ForegroundColor Red
          Send-MailMessage -To $errRecip -Subject "$script - Error occurred during processing" -Body $err -From $sender -Attachment $logfile -SmtpServer $smtpServer
          Exit
      }
      
      #CHECK FOR EWS MANAGED API, IF PRESENT IMPORT THE HIGHEST VERSION EWS DLL, ELSE EXIT
      $EWSDLL = (($(Get-ItemProperty -ErrorAction SilentlyContinue -Path Registry::$(Get-ChildItem -ErrorAction SilentlyContinue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Web Services'|Sort-Object Name -Descending | Select-Object -First 1 -ExpandProperty Name)).'Install Directory') + "Microsoft.Exchange.WebServices.dll")
      If (Test-Path $EWSDLL)
      {
          Try
          {
              Import-Module $EWSDLL -DisableNameChecking -ErrorAction Stop
          }
          Catch 
          {
              $err = "An error occurred importing the Exchange Web Services DLL '$EWSDLL'. Error: $_"
              Write-Host "`n$err" -ForegroundColor Red
              Send-MailMessage -To $errRecip -Subject "$script - Error occurred during processing" -Body $err -From $sender -Attachment $logfile -SmtpServer $smtpServer
              Exit
          }
      }
      Else
      {
          $err = "This script requires the EWS Managed API 1.2 or later. Please download and install the current version of the EWS Managed API from http://go.microsoft.com/fwlink/?LinkId=255472"
          Write-Host "`n$err" -ForegroundColor Red
          Send-MailMessage -To $errRecip -Subject "$script - Error occurred during processing" -Body $err -From $sender -Attachment $logfile -SmtpServer $smtpServer
          Exit
      }
      
      
      #Create EWS Object
      $ews = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList "Exchange2013_SP1" -ErrorAction Stop
      
      #Authenticate EWS using OAuth
      Try {
          $ews.UseDefaultCredentials = $False
          Write-Host "Requesting EWS OAuth Token using registered Client ID" -ForegroundColor Yellow
      
          $OAuthResult = Get-EWSOAuthToken -UserPrincipalName $UserPrincipalName -Password $Password -ClientId "$ClientIDfromAzureAD" -ErrorAction Stop
          $token = $OAuthResult.Result.AccessToken
      
      #Check if we successfully retrieved an Oauth Token
      If ([System.String]::IsNullOrEmpty($token))
              {
                  $err = "Get-EWSOAuthtoken returned an empty Auth Token. Aborted. Latest error details:`n$_error $($OAuthResult.Exception)"
                  Write-Host "`n$err" -ForegroundColor Red
                  $OAuthResult | Format-List -Force
                  $OAuthResult.Result | Format-List -Force
                  Send-MailMessage -To $errRecip -Subject "$script - Error occurred during processing" -Body "$err" -From $sender -Attachment $logfile -SmtpServer $smtpServer
                  Exit
              }
              else
              {
                  $OAuthchk = $true
                  $ews.Credentials = [Microsoft.Exchange.WebServices.Data.OAuthCredentials]$token
                  Write-Host "Set EWS credentials to OAuth token" -ForegroundColor Yellow
              }
          }
      Catch
      {
          $err = "An error occurred creating a new EWS object. Error:`n $_"
          write-host "`n$err" -ForegroundColor Red
          Send-MailMessage -To $errRecip -Subject "$script - Error occurred during processing" -Body "$err" -From $sender -Attachment $logfile -SmtpServer $smtpServer
          Exit
      }
      
      # Do your processing using EWS
      ....