割り当てのスクリプト - 取得
注:
このスクリプトは、PowerShell ISE では実行できません。
以下は、取得用の PowerShell スクリプトです - ユーザー クラス。
<#
.Synopsis
Get the user classes info like in which classes the user is member and what is the user role of the user in those classes.
.DESCRIPTION
Scripts reads the file and get all the classids and updates the role with the userrole mentioned, if not mentioned assign to student which is default. Then it gets the classes in which the user is owner and classes where the user is member. Script refines and generates the output with the class details and role of user in specific class.
.Example
.\Get-userClasses.ps1 -userId <specific user Id>
This will get the user details according to user membership
.\Get-userClasses.ps1 -userId <specific user Id> -classIdsFile <complete csv file path>
This will get the user details of classes specified in csv file and user membership, if we don't pass the userRole parameter, it will be assigned to Student default for the classIds specified in csv file
.\Get-userClasses.ps1 -userId <specific user Id> -classIdsFile <complete csv file path> -userrole <Student or Teacher>
This will get the user details of classes specified in csv file and user membership. For the classids specified in file user data is generated according to the userrole specified(Teacher or Student)
.Parameter userId
UserId of the user to export and delete submissions
.Parameter classIdsFile
Full path to a plain text file which contains a single classId on each line.
sample list of classIds. Each line should have single classId
e81c2cd2-e3ff-4c0a-8ed0-63df43ff884c
044b4c35-5fab-454a-9705-bc750108c059
e81c2cd2-4c0a-e3ff-9705-bc750108c059
.Parameter userrole
This parmeter is used to specify the role of the user to be used for the class ids present in classIdsFile and the user is removed from class.
.paramter outputFileName
This parameter is used to name the output file of the script, no extensions. This is not mandatorty by default the output file name is UserClassDetails
#>
param(
[Parameter(Mandatory=$true, Position=1)]
[ValidateNotNullOrEmpty()]
[ValidateScript({
try {
[System.Guid]::Parse($_) | Out-Null
$true
} catch {
throw $_
}
})]
[string] $userId,
[parameter(Mandatory=$false, Position=2)]
[ValidateNotNullOrEmpty()]
[ValidateScript({
if(-Not ($_ | Test-Path) ){
throw "File or folder does not exist"
}
if(-Not ($_ | Test-Path -PathType Leaf) ){
throw "The classIdsFile argument must be a file. Folder paths are not allowed."
}
if($_ -notmatch "(\.txt)"){
throw "The file specified in the path argument must be of type txt"
}
return $true
})]
[string] $classIdsFile,
[Parameter(Mandatory=$false, Position=3)]
[ValidateNotNullOrEmpty()]
[ValidateSet('Student','Teacher', ignorecase=$false)]
[string] $userrole = "Student",
[parameter(Mandatory=$false, Position=4)]
[ValidateNotNullOrEmpty()]
[string] $outputFileName = "UserClassDetails"
)
# Load ADAL
#Add-Type -Path ".\ADAL\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
# Load MSAL
if ( -not(Get-Module Microsoft.Identity.Client -ListAvailable) ) {
Install-Module Microsoft.Identity.Client -Force -Scope CurrentUser -ErrorAction Stop
}
Import-Module Microsoft.Identity.Client
$script:maxRetryAttempt = 3
$script:authenticationResult = $null
$graphEndpoint = "https://graph.microsoft.com"
$authString = "https://login.windows.net/common"
# Output to summarize success/failure of API calls.
$script:getClassDetailsReport = @()
#Makes Web request and logs the response status
function Invoke-RequestWithRetry
{
param(
[Parameter(Mandatory=$true)]$url,
[Parameter(Mandatory=$false)]$classId,
[Parameter(Mandatory=$false)]$className
)
for($i=1; $i -le $script:maxRetryAttempt; $i++)
{
try
{
$tempResult = Invoke-WebRequest -Method Get -Uri $url -Headers $script:authHeaders
$script:getClassDetailsReport += [PSCustomObject]@{
RequestUrl = $url
Method = "Get"
ResponseCode = $tempResult.StatusCode
ClassName = $className
ClassId = $classId
RequestId = $tempResult.Headers["request-id"]
StatusDescription = $tempResult.StatusDescription
NumberOfAttempts = $i
}
return $tempResult
}
catch
{
if($_.Exception.Response -ne $null)
{
$responseCode = $_.Exception.Response.StatusCode.Value__
$requestId = $_.Exception.Response.Headers["request-id"]
}
$script:getClassDetailsReport += [PSCustomObject]@{
RequestUrl = $url
Method = "Get"
ResponseCode = $responseCode
ClassName = $className
ClassId = $classId
RequestId = $requestId
StatusDescription = $_.Exception.Message
NumberOfAttempts = $i
}
if($i -eq $script:maxRetryAttempt)
{
throw $_.Exception.Message
}
if($responseCode -eq 401)
{
$script:authHeaders = Get-AuthHeaders -useRefreshToken $true
}
}
}
}
#Get the authheaders
function Get-AuthHeaders {
Param(
[Parameter(Mandatory = $false)]
[bool] $useRefreshToken = $false
)
$pcaOptions = [Microsoft.Identity.Client.PublicClientApplicationOptions]::new()
$pcaOptions.ClientId = "eb2298a1-a6bb-4f16-a27a-b582815db47b"
$pcaOptions.RedirectUri = New-Object System.Uri("urn:ietf:wg:oauth:2.0:oob")
$pcaBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::CreateWithApplicationOptions($pcaOptions)
$pca = $pcaBuilder.Build()
$scopes = New-Object System.Collections.Generic.List[string]
$scopes.Add("EduRoster.ReadBasic")
$scopes.Add("Group.Read.All")
$authResult = $pca.AcquireTokenInteractive($scopes)
if ($useRefreshToken -eq $false) {
$script:token = $authResult.ExecuteAsync()
while ( $script:token.IsCompleted -eq $False ) { <# Waiting for token auth flow to complete #> }
}
else {
$script:token = $pca.AcquireTokenByRefreshToken($scopes, $script:token.Result.AccessToken)
}
$authHeader = $script:token.Result.TokenType + " " + $script:token.Result.AccessToken
$headers = @{"Authorization" = $authHeader; "Content-Type" = "Application/json" }
return $headers
}
#Get the group Name
function Get-ClassName
{
param(
[Parameter(Mandatory=$true)]$classId
)
$getClassDetailsUrl = "{0}/v1.0/groups/{1}" -f $graphEndpoint, $classId
$getClassDetailsResult = (Invoke-RequestWithRetry -url $getClassDetailsUrl) | ConvertFrom-Json
$className = $getclassDetailsResult.displayName
return $className
}
#Get ownership details of user id using edu endpoit and refine with the creation type to assignments
function Get-OwnershipDetails
{
param(
[Parameter(Mandatory=$true)]$userId
)
$ownershipUrl = ("{0}/edu/users/{1}/ownedobjects?`$top=999" -f $graphEndpoint,$userId)
$ownershipQuery = (Invoke-RequestWithRetry -url $ownershipUrl) | ConvertFrom-Json
$classes = $ownershipQuery.value | Where-Object {$_.creationOptions -contains "classAssignments" } | Select-Object objectId, displayName
return $classes
}
#Get the membership details of user id using edu endpoint and refine with the creation type to assignments
function Get-MembershipDetails
{
param(
[Parameter(Mandatory=$true)]$userId
)
$membershipUrl = ("{0}/edu/users/{1}/memberof?`$top=999" -f $graphEndpoint,$userId)
$membershipQuery = (Invoke-RequestWithRetry -url $membershipUrl) | ConvertFrom-Json
$classes = $membershipQuery.value | Where-Object {$_.creationOptions -contains "classAssignments" } | Select-Object objectId, displayName
return $classes
}
#Return custom pscutom object which have classid, userid, classname, role, getsubmissionprocessed and deletesubmissionprocessed properties
function Generate-ClassRecord
{
param(
[Parameter(Mandatory=$true)]$userId,
[Parameter(Mandatory=$true)]$classId,
[Parameter(Mandatory=$true)]$role,
[Parameter(Mandatory=$false)]$displayName
)
$classRecord = [PSCustomObject]@{
ClassId = $classId
UserId = $userId
ClassName = $displayName
Role = $role
GetSubmissionsProcessed = $false
DeleteSubmissionsProcessed = $false
}
return $classRecord
}
$script:authHeaders = Get-AuthHeaders
# This will contain the details for all "interesting" classes
$script:classDetails= @{}
# Find owned classes (where user is currently a teacher)
try
{
$ownedClasses = Get-OwnershipDetails -userId $userId
foreach($class in $ownedClasses)
{
if(-NOT $script:classDetails.ContainsKey($class.objectId))
{
$classRecord = Generate-ClassRecord -userId $userId -classId $class.objectId -role "Teacher" -displayName $class.displayName
$script:classDetails.Add($class.objectId, $classRecord)
}
}
}
catch
{
Write-Error $_.Exception.Message
}
# Find joined groups (where user is currently a student)
try
{
$joinedClasses = Get-MembershipDetails -userId $userId
foreach($class in $joinedClasses)
{
if(-NOT $script:classDetails.ContainsKey($class.objectId))
{
$classRecord = Generate-ClassRecord -userId $userId -classId $class.objectId -role "Student" -displayName $class.displayName
$script:classDetails.Add($class.objectId, $classRecord)
}
}
}
catch
{
Write-Error $_.Exception.Message
}
# Find details for the additional groups from the file.
if(![string]::IsNullOrEmpty($classIdsFile))
{
$classIdsFromFile = Select-String -Pattern "\w" -Path $($classIdsFile) | ForEach-Object{
$_.Line
}
foreach ($classId in $classIdsFromFile)
{
# List of user's current classes takes precendence over the additional set of classes
# i.e. if we've already identified the role, we don't need to do it again.
if(-NOT $script:classDetails.ContainsKey($classId.Trim("")))
{
try
{
$displayName = Get-ClassName -classId $classId
$classRecord = Generate-ClassRecord -userId $userId -classId $classId -role $userrole -displayName $displayName
$script:classDetails.Add($classId, $classRecord)
}
catch
{
Write-Host $_.Exception.Message
}
}
}
}
$script:classDetails.Values | Export-Csv -Path .\$($outputFileName).csv -NoTypeInformation
$script:getClassDetailsReport | Export-Csv -Path .\UserClassDetailsReport.csv -NoTypeInformation
$directoryPath = (Get-Item -Path ".\" -Verbose).FullName
Write-Host "Class details file($($outputFileName).csv) is generated at $directoryPath\($($outputFileName).csv)"
Write-Host "Class details report(UserClassDetailsReport.csv) is generated at $directoryPath\UserClassDetailsReport.csv"