Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Assignments Scripts - Get

Note

This script cannot be run in PowerShell ISE.

Below are the PowerShell scripts for Get - user classes.

<#
 .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"

Additional resources