diklabu_nextcloudVWN.psm1
# . $PSSCRIPTROOT\get-untisClassTeacherTeams.ps1 # Functions for reading from UNtis # (nur für Tests, sofern nicht schon geladen über diklabu) # ##### DIKLABU_NEXTCLOUDVWN.PSM1 ##### Dieses Modul muss mit Powershell x64 (7.1 und höher) interpretiert werden wegen invoke-webrequest -custommethod ##### Es enthält Funktionen, um mit der Nextcloud zu kommunizieren # get-NCparameters: Liest die Systemparameter für die Nextcloudfunktionen aus # get-LoginCreds: Liest die Credentials für den angegebenen User entweder aus Datei, aus Konfiguration oder per Benutzereingabe aus # new-NCfolder: Legt einen Ordner in der Nextcloud an # set-NCuserShare: Teilen eines Nextcloud Ordners oder Datei # get-NCuserShares: Get Shares from a specific file or folder # delete-NCuserShare: Delete Share from a specific file or folder # new-NCuserIDlist: Create a list of Nextcloud User IDs from Nextcloud # test-NCpath: Test if a file or folder exists in Nextcloud # upload-NCfile: Upload a file to Nextcloud # new-NCfolders: Create a folder structure in Nextcloud for every class # is-Under18: Prüft, ob ein SoS minderjährig ist # new-classList: Erstellt eine Klassenliste mit Daten aus BBS-Planung und Active Directory des Schulnetzes # new-NCclassLists: Erstellt csv-Listen, ähnlich wie Klassenlisten mit E-mail in BBS Planung und legt sie in der Nextcloudstruktur der Klasse ab # ************************************** get-NCparameters ************************************ # <# .Synopsis Liest die Systemparameter für die Nextcloudfunktionen aus .DESCRIPTION Liest die Systemparameter für die Nextcloudfunktionen aus einer json-Datei aus oder legt diese mit Defaultwerten an, wenn die Datei nicht existiert. Default- verzeichnis ist das Benutzerverzeichnis des angemeldeten Benutzers. Defaultdateiname ist ncParams.json. .PARAMETER file Parameterdatei für alle Nextcloud VWN Dienste .EXAMPLE get-NCparameters .EXAMPLE get-NCparameters -file c:\Temp\keys #> function get-NCparameters { [CmdletBinding()] Param ( # Parameterdatei für alle Nextcloud VWN Dienste [Parameter(Position=0)] $file="$env:USERPROFILE\ncParams.json" ) Begin {} Process { $ncParams=@{} if (Test-Path $file) { $pf = Get-Content $file | ConvertFrom-Json $pf.PSObject.Properties | ForEach-Object {$ncParams[$_.Name]=$_.Value} } else{ if ($global:ncParams) { $global:ncParams.Clear() } $ncParams.add('allgCsvDelimiter',';') $ncParams.add('allgLogfile', "$env:USERPROFILE\ncactions.txt") # logfile NC # $ncParams.add('BPpathBbsPlan', "c:\access\plan") # BBS-Planung base directory $ncParams.add('BPBackupRootDir', "C:\access\plan\Backup") # Verw.-Netz TS: D:\Programme\BBS-Planung\Sicherung $ncParams.add('CWAteachersClasses', "$env:USERPROFILE\cwaTeachersClasses.csv") # file to store list of teachers and organizational units in cwa $ncParams.add('EMAILsender', "nextcloudvwl@mmbbs.de") # E-Mail Sender (From:) $ncParams.add('EMAILadminUser', "vwl\nextcloudvwl") # E-Mail Admin User $ncParams.add('EMAILadminPass', "") # just a placeholder, PW is stored in a securefile after first entry $ncParams.add('EMAILpassFile',"$env:USERPROFILE\email.txt") # secure file to save creds nextcloud $ncParams.add('EMAILbodyFile',"$env:USERPROFILE\emailbody.txt") # emailbody text, text included in <> is variable $ncParams.add('EMAILsubject',"<Klasse>: Änderung von Daten der Lernenden") # email subject, text included in <> is variable $ncParams.add('EMAILserver',"ex.mmbbs.de") # Exchange server mmbbs.de $ncParams.add('EMAILport',"587") # smtp port $ncParams.add('LDAPmm-bbsURI', '172.31.0.41:389') # LDAP server in schoolnet to get students email addresses $ncParams.add('LDAPuserName', 'ldap-user') # Username for access to LDAP Server $ncParams.add('LDAPuserPass', '') # LDAP secure PW temporary $ncParams.add('LDAPuserCredsFile', "$env:USERPROFILE\lu.txt") # LDAP creds secure file $ncParams.add('LDAPsusFilePath', "$env:USERPROFILE\ldapSuS.csv") # list of student information from LDAP $ncParams.add('LDAPlulFilePath', "$env:USERPROFILE\ldapLuL.csv") # list of teacher information from LDAP $ncParams.add('NCuriDav','https://nextcloud.mmbbs.de/remote.php/dav/files/799264EF-ADE2-4469-8F70-73A00944C255') # webdav keadmin $ncParams.add('NCuriOcsShares', 'https://nextcloud.mmbbs.de/ocs/v2.php/apps/files_sharing/api/v1/shares') $ncParams.add('NCuriOcsUsers', 'https://nextcloud.mmbbs.de/ocs/v1.php/cloud/users') $ncParams.add('NCrootFolderName', "/Klassen") $ncParams.add('NCsusListenFolderName', "Betriebs- und Lernendenlisten") $ncParams.add('NCadminUser', "keadmin") # Nextcloud Admin User $ncParams.add('NCadminPass', "") # just a placeholder, PW is stored in a securefile after first entry # Das App Passwort kann aus Sicherheitsgründen in Nextcloud nur einmal direkt nach der Erstellung angezeigt werden $ncParams.add('NCpassFile',"$env:USERPROFILE\nc.txt") # secure file to save creds nextcloud $ncParams.add('NClistOfAdditionalSharers', "HR,SO,OP,SR") # Users beyond class team who get global access $ncParams.add('NCtextMinderjaehrig', 'Minderjährig') $ncParams.add('NCtextErwachsen', '') $ncParams.add('NCpathOldClassLists', "$env:USERPROFILE\NColdClassLists") # folder to compare new and old lists $ncParams.add('NCpathNewClassLists', "$env:USERPROFILE\NCnewClassLists") # to evaluate if both differ $ncParams.add('WUlocation', "https://borys.webuntis.com/WebUntis/jsonrpc.do?school=MMBbS%20Hannover") # webuntis url $ncParams.add('WUuser', "kemmrieskurs") # Webuntis user to access data with $ncParams.add('WUpass', "") # just a placeholder, PW is stored in a securefile after first entry $ncParams.add('WUpassFile',"$env:USERPROFILE\wu.txt") # secure file to save creds webuntis $ncParams.add('WUlocationClassTeachers', "$env:USERPROFILE\classesTeachers.csv") # csv file with classes and their teacher team $ncParams.add('WUclassesTeachersDelimiter',',') # Separator between teachers in classteacherlist $ncParamsString = $ncParams | ConvertTo-Json $ncParamsString | Set-Content -Path $file } $global:ncParams=$ncParams; # sicherstellen, dass die Passwörter in den Dateien vorhanden sind $tempcreds = get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile" $tempcreds = get-LoginCreds -userKey "EMAILadminUser" -passKey "EMAILadminPass" -passFileKey "EMAILpassFile" $tempcreds = get-LoginCreds -userKey "LDAPuserName" -passKey "LDAPuserPass" -passFileKey "LDAPuserCredsFile" $tempcreds = get-LoginCreds -userKey "WUuser" -passKey "WUpass" -passFileKey "WUpassFile" $tempcreds | Out-Null # just to avoid unused variable warning return $ncParams; } } # ************************************** end get-NCparameters ************************************ # # ************************************** get-LoginCreds ************************************ # <# .Synopsis Liest die Credentials für den angegebenen User entweder aus Datei, aus Konfiguration oder per Benutzereingabe aus .DESCRIPTION Liest die Credentials für den angegebenen User entweder aus Datei, aus Konfiguration oder per Benutzereingabe aus. .EXAMPLE get-LoginCreds -userKey $userConfigKey -passKey $passConfigKey -passfileKey $passFilenameConfigKey #> function get-LoginCreds { [CmdletBinding()] Param ( # Username Key in global Config [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$userKey, # Pasword Key in global Config [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [String]$passKey, # Pasword Key in global Config [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)] [String]$passFileKey ) Begin {} Process { # Konfigdaten einlesen, wenn notwendig if (!$global:ncParams.NCpassFile) { # hier muss ein existierender Subparameter eingetragen sein (z.B. "allgemein"), um auf Vorhandensein zu prüfen get-NCparameters # Konfigdaten laden } if (!(test-path($global:ncParams.$passFileKey))) { # input admin pw $global:ncParams.$passKey = ((Get-Credential -username $global:ncParams.$userKey -Message "Passwort für User $userKey eingeben:").password | ConvertFrom-SecureString) # and store in secure file $global:ncParams.$passKey > $global:ncParams.$passFileKey } else { $global:ncParams.$passKey = Get-Content -Path $global:ncParams.$passFileKey } $pw = $global:ncParams.$passKey | ConvertTo-SecureString $creds = New-Object System.Management.Automation.PSCredential $global:ncParams.$userKey, $pw return $creds } } # ************************************** end get-LoginCreds ************************************ # # ************************************** new-NCfolder ************************************ # <# .Synopsis Legt einen Ordner in der Nextcloud an .DESCRIPTION Legt einen Ordner in der Nextcloud an, falls dieser noch nicht existiert .PARAMETER rootfoldername Basisverzeichnis, in dem der neue Ordner angelegt werden soll Angabe ohne das WebDAV-Basisverzeichnis Default ist "/" .PARAMETER newfoldername Name des anzulegenden Ordners vorhandende führendes oder schließendes / wird entfernt .EXAMPLE new-NCfolder "/basefolder" "newfolder" #> function new-NCfolder { Param ( # Basefolder to start from [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$rootfoldername="/", # New folder name [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [String]$newfoldername ) Begin{ # Zusammengefasst bereitet dieser Code-Abschnitt die notwendigen # Authentifizierungsinformationen vor, um sichere HTTP-Anfragen an Nextcloud, # zu ermöglichen. $funcName = $MyInvocation.InvocationName # wie heißt diese Funktion? $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $headers = @{ "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))" } } Process { $newfoldername=$newfoldername.TrimStart("/") $newfoldername=$newfoldername.TrimEnd("/") if ($rootfoldername -eq "/"){ $uri=$global:ncParams['NCuriDav'].TrimEnd("/")+$rootfoldername+$newfoldername } else{ $rootfoldername=$rootfoldername.TrimStart("/") $rootfoldername=$rootfoldername.TrimEnd("/") $uri=$global:ncParams['NCuriDav'].TrimEnd("/")+"/"+$rootfoldername+"/"+$newfoldername } # Folder schon vorhanden? $folderexists=test-NCpath -Uri $uri if (!$folderexists){ Try { $inv=Invoke-WebRequest -Uri $uri -customMethod 'MKCOL' -headers $headers } catch { write-msg -msg "$funcName : Folder kann nicht angelegt werden: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null } } } } # ************************************** end new-NCfolder ************************************ # # ************************************** set-NCuserShare ************************************ # <# .Synopsis Teilen eines Nextcloud Ordners oder Datei .DESCRIPTION Share a file/folder with a user/group or as public link. Syntax: /shares Method: POST POST Arguments: path - (string) path to the file/folder which should be shared POST Arguments: shareType - (int) 0 = user; 1 = group; 3 = public link; 4 = email; 6 = federated cloud share; 7 = circle; 10 = Talk conversation POST Arguments: shareWith - (string) user / group id / email address / circleID / conversation name with which the file should be shared POST Arguments: publicUpload - (string) allow public upload to a public shared folder (true/false) POST Arguments: password - (string) password to protect public link Share with POST Arguments: permissions - (int) 1 = read; 2 = update; 4 = create; 8 = delete; 16 = share; 31 = all (default: 31, for public shares: 1) POST Arguments: expireDate - (string) set a expire date for public link shares. This argument expects a well formatted date string, e.g. ‘YYYY-MM-DD’ POST Arguments: note - (string) Adds a note for the share recipient. POST Arguments: attributes - (string) URI-encoded serialized JSON string for share attributes Mandatory fields: shareType, path and shareWith for shareType 0 or 1. Result: XML containing the share ID (int) of the newly created share Statuscodes: 100 - successful 400 - unknown share type 403 - public upload was disabled by the admin 404 - file couldn’t be shared .PARAMETER itemPath Name der Ressource ohne WebDAV Basis URI, z.B. /Klassen/FISI21F .PARAMETER userID Nextcloud UserID für die der Zugriff geschaffen werden soll .EXAMPLE set-NCuserShare -path "Klassen/FISI23D" #> function set-NCuserShare { Param ( # Folder or file to be shared [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$itemPath, # without WebDAV Base URI, e.g. FISI21F # Nextcloud User ID [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [String]$userID ) Begin{ $funcName = $MyInvocation.InvocationName # wer bin ich? $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $headersDav = @{ "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } $headersOcs = @{ "OCS-APIRequest" = "true"; "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } } Process { $error.clear() if (!($itemPath.StartsWith("/")) -and $itemPath -ne "/"){ $itemPath="/"+$itemPath } $uri=($global:ncParams['NCuriDav']).TrimEnd("/")+$itemPath # Folder/ File exists? $folderexists=test-NCpath -Uri $uri if ($folderexists){ $body= @{ 'shareType'=0; 'shareWith'=$userID; 'permissions'=31; 'path'=$itemPath; } Try { write-msg -msg "$funcName : gebe Zugriff an userID $userid für $itempath" -path_prot $global:ncParams['allgLogfile']| Out-Null $inv=Invoke-WebRequest -uri $global:ncParams['NCuriOcsShares'] -headers $headersOcs -Method 'POST' -Body $body return $true } catch { write-msg -msg "$funcName : Fehler bei Invoke-Webrequest: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null return $false } } else{ write-msg -msg "$funcName : Datei/ Folder existiert nicht: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null return $false } } } # ************************************** end set-NCuserShare ************************************ # # ************************************** get-NCuserShares ************************** # <# .Synopsis Get Shares from a specific file or folder .DESCRIPTION Get all shares from a given file/folder. Syntax: /shares Method: GET URL Arguments: path - (string) path to file/folder URL Arguments: reshares - (boolean) returns not only the shares from the current user but all shares from the given file. URL Arguments: subfiles - (boolean) returns all shares within a folder, given that path defines a folder Mandatory fields: path Result: XML with the shares Statuscodes: 100 - successful 400 - not a directory (if the ‘subfile’ argument was used) 404 - file doesn’t exist .EXAMPLE get-NCuserShares -path "Klassen/FISI23D" .EXAMPLE get-NCuserShares -path "Klassen/FISI23D" -reshares $false #> function get-NCuserShares { Param ( # Folder or file to be shared [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$itemPath, # with Base URI, e.g. /Klassen/FISI24F # Nextcloud User ID [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=1)] [Boolean]$reshares=$true ) Begin{ $funcName = $MyInvocation.InvocationName # wer bin ich? $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $headersDav = @{ "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } $headersOcs = @{ "OCS-APIRequest" = "true"; "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } } Process { $error.clear() if (!($itemPath.StartsWith("/")) -and $itemPath -ne "/"){ $itemPath="/"+$itemPath } $uri=$global:ncParams['NCuriDav']+$itemPath # Folder/ File exists? $folderexists=test-NCpath -Uri $uri if ($folderexists){ $resharesString ="TRUE" if (!$reshares) {$resharesString="FALSE"} $url=$global:ncParams['NCuriOcsShares'] + "?" + "path=" + $itemPath + "&" + "reshares=" + $resharesString Try { write-msg -msg "$funcName : requesting user shares for file $itempath from server ..." -path_prot $global:ncParams['allgLogfile']| Out-Null write-msg -msg "$funcName : building list of share_with IDs for file/ folder $itempath ..." -path_prot $global:ncParams['allgLogfile']| Out-Null $sharesList=@{} foreach ($element in ([xml]$inv.content).ocs.data.element){ $sharesList.add($element.share_with, $element.id) } return $sharesList } catch { write-msg -msg "$funcName : Error while Invoke-Webrequest: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null return $false } } else{ write-msg -msg "$funcName : File/ folder doesn't exist: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null return $false } } } # ************************************** end get-NCuserShares ************************************ # # ************************************** delete-NCuserShare ************************************ # <# .Synopsis Delet Share from a specific file or folder .DESCRIPTION Delete a share from a given file/folder. Syntax: /shares Method: DELETE URL: path - (string) path to file/folder Statuscodes: 100 - successful 400 - not a directory (if the ‘subfile’ argument was used) 404 - file doesn’t exist .PARAMETER itemPath Folder or file to delete share from .PARAMETER shareID Share ID to delete .EXAMPLE delete-NCuserShare -itemPath "Klassen/FISI23D" -shareID 123 #> function delete-NCuserShare { Param ( # Folder or file to be shared [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$itemPath, # without Base URI, e.g. FISI21F, NOT: /Klassen/SJ22-23/FISI21F # Nextcloud User ID [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [String]$shareID ) Begin{ $funcName = $MyInvocation.InvocationName # wer bin ich? $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $headersDav = @{ "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } $headersOcs = @{ "OCS-APIRequest" = "true"; "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } } Process { $error.clear() if (!($itemPath.StartsWith("/"))){ $itemPath="/"+$itemPath } $uri=$global:ncParams['NCuriDav']+$itemPath # Folder/ File exists? $folderexists=test-NCpath -Uri $uri if ($folderexists){ $uri= $global:ncParams['NCuriOcsShares'] + '/' + $shareID Try { $inv=Invoke-WebRequest -uri $uri -headers $headersOcs -Method 'DELETE' write-msg -msg "$funcName : deleting user share: $shareID in folder: $itemPath" -path_prot $global:ncParams['allgLogfile']| Out-Null } catch { write-msg -msg "$funcName : error in Invoke-Webrequest: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null } } } } # ************************************** end delete-NCuserShare ************************************ # # ********** Create hashtable of teacher initials vs email and Nextcloud User ID set-NCuserShare ******** # # ************************** new-NCuserIDlist ******************************************* # <# .SYNOPSIS Create a list of Nextcloud User IDs from Nextcloud .DESCRIPTION Create a list of Nextcloud User IDs from Nextcloud. The list is a hashtable with the teacher initials as key and the Nextcloud User ID as value. If the teacher initials are not found in the BBS-Planung, the email address is used as key. Teacher initials are stored in the BBS-Planung. We use the backup directory of BBS-Planung to avoid the need of a database connection since that doesn't work with Powershell 7 (DB BBS-Planung is 32 bit only) .PARAMETER None .EXAMPLE new-NCuserIDlist #> function new-NCuserIDlist { Param ( ) Begin{ $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $NCuriOcsUsers=$global:ncParams['NCuriOcsUsers'] $headersOcs = @{ "OCS-APIRequest" = "true"; "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))"; } # Get all User IDs $userIDs= [xml](Invoke-WebRequest -uri $NCuriOcsUsers -headers $headersOcs -Method 'GET').content # Get Teacher initials from BBS-Planung # unfortunately this doesn't work with Powershell 7, so use the none DB option in get-BpTeachers $bpTeachersRaw = get-BpTeachers -useDB $false -bpBackupRootDir $global:NCparams['BPBackupRootDir'] $bpTeachers=@{} # key is email, data is initial foreach ($t in $bpTeachersRaw){ $bpTeachers[$t.'email']=$t.KÜRZEL # key is unfortunately "KÜRZEL" } } Process { $error.clear() $userEmail_ID=@{} foreach ($id in $userids.ocs.data.users.element){ # iterate all users IDs $uri = "$($global:NCparams['NCuriOcsUsers'])/$id" Try{ $userprops=[xml](Invoke-WebRequest -Uri $uri -Method 'GET' -headers $headersOcs).content Try { # E-Mail address from Verwaltungsnetz exists in BBS-Planung $initials=$bpTeachers[$userprops.ocs.data.email] } catch{ # Email address not stored in BBS-Planung, leave with original nextcloud email $initials=$userprops.ocs.data.email } $userEmail_ID.($initials) = $id } catch{ # User doesn't exist $error.clear() } } return $userEmail_ID } } # ************************** end new-NCuserIDlist ********************************** # # ************************** test-NCpath ******************************************* # <# .SYNOPSIS Test if a file or folder exists in Nextcloud .DESCRIPTION Test if a file or folder exists in Nextcloud. The function returns $true if the file or folder exists, otherwise $false. .PARAMETER uri Nextcloud Base URI + Folder [+ File ] Name .EXAMPLE test-NCpath -uri "/Klassen/FISI23A" #> function test-NCpath { Param ( # Nextcloud Base URI + Folder [+ File ] Name [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$uri ) Begin { $funcName = $MyInvocation.InvocationName # wer bin ich? $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $headers = @{ "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))" } } Process { $error.clear() # File schon vorhanden? Try { # -customMethod Parameter works with Powershell 7.1 and higher only !!!!! $inv=Invoke-WebRequest -Uri $uri -customMethod 'PROPFIND' -headers $headers $uriexists=$true } catch { # File doesn't exist $uriexists=$false write-msg -msg "$funcName : Error with Invoke-Webrequest: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null $error.clear() } return $uriexists } } # ************************** end test-NCpath ********************************** # # ************************** upload-NCfile ******************************************* # <# .SYNOPSIS Upload a file to Nextcloud .DESCRIPTION Upload a file to Nextcloud. The function returns $true if the file was uploaded successfully, otherwise $false. .PARAMETER sourceFileUri Sourcefile URI in local file system .PARAMETER destRootFolder Destination Rootfolder in Nextcloud (e.g. /Klassen/FISI23A) DAV-baseaddress is fixed in this module because it's technically a concern of the Nextcloud instance, not the one of the calling script .PARAMETER destFile Destination Filename in Nextcloud (e.g. myDocument.txt) .PARAMETER overwrite $true is Nextcloud default, but for security it's set here to $false by default .EXAMPLE upload-NCfile -sourceFileUri "c:\temp\myDocument.txt" -destRootFolder "/Klassen/FISI23A" -destFile "myDocument.txt" #> function upload-NCfile { Param ( # Sourcefile URI in local file system [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=0)] [String]$sourceFileUri, # Destination Rootfolder in Nextcloud (e.g. /Klassen/FISI23A) # DAV-baseaddress is fixed in this module because it's technically a concern of the Nextcloud instance, # not the one of the calling script [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [String]$destRootFolder, # Destination Filename in Nextcloud (e.g. myDocument.txt) [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)] [String]$destFile, # $true is Nextcloud default, but for security it's set here to $false by default [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] [Boolean]$overwrite=$false ) Begin{ $funcName = $MyInvocation.InvocationName $adminuser=(get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").UserName $apppass= ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "NCAdminUser" -passKey "NCadminPass" -passFileKey "NCpassFile").Password -AsPlainText $headers = @{ "Authorization" = "Basic $([Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("${adminuser}:${apppass}"))))" "Content-Type" = "text/csv" } $error.clear() } Process { # Build complete filename $destFile=$destFile.Replace("/","") if ($destRootFolder -eq "/"){ $uri=$global:ncParams['NCuriDav']+$destRootFolder+$destFile } else{ $destRootFolder=$destRootFolder.TrimStart("/") $destRootFolder=$destRootFolder.TrimEnd("/") $uri=$global:ncParams['NCuriDav']+"/"+$destRootFolder+"/"+$destFile } # File already exists? if($overwrite){ $fileexists=$false } else{ $fileexists=test-NCpath -Uri $uri } if (!$fileexists){ Try { $body=$(Get-Content $sourceFileUri -raw) $inv=Invoke-WebRequest -Uri $uri -Method 'PUT' -headers $headers -body $body } catch { write-msg -msg "$funcName : Error with Invoke-Webrequest: $uri" -path_prot $global:ncParams['allgLogfile']| Out-Null $Error } } } } # end upload-nextCloudFile # ************************************** end upload-nextCloudFile ************************************ # # ************************************** new-NCfolders ************************************' <# .SYNOPSIS Create a folder structure in Nextcloud for each class .DESCRIPTION Create a folder structure in Nextcloud for each class. The structure is as follows: - Class as headline - Enrollment documents incl. signature lists - Company and student lists - Certificates with subfolders 1st, 2nd, 3rd year and there subfolders Winter/Summer - Class meetings - Excuses and exemptions The function reads the class:teacher hashtable from Untis or file and creates a list of teacher initials and Nextcloud User ID. .EXAMPLE new-NCfolders #> function new-NCfolders{ # ******************************** main *********************************************** # # Struktur Klassenordner Nextcloud: # Klasse als Überschrift # Einschulungsunterlagen incl. Unterschriftenlisten # Betriebsliste mit E-Mail-Adressen # Zeugnisse mit Unterordnern 1. AJ, 2. AJ, 3. AJ # und dort Unterordner Winter/Sommer # Klassenbesprechungen # Entschuldigungen-Freistellungen Begin{ $funcName = $MyInvocation.InvocationName # wer bin ich? $subfolderURIs = @() $subfolderURIs += "Einschulungsunterlagen Unterschriftenlisten" $subfolderURIs += "Betriebs- und Lernendenlisten" $subfolderURIs += "Zeugnis" $subfolderURIs += "Zeugnis"+"/"+"1. AJ" $subfolderURIs += "Zeugnis"+"/"+"1. AJ"+"/"+"Winter" $subfolderURIs += "Zeugnis"+"/"+"1. AJ"+"/"+"Sommer" $subfolderURIs += "Zeugnis"+"/"+"2. AJ" $subfolderURIs += "Zeugnis"+"/"+"2. AJ"+"/"+"Winter" $subfolderURIs += "Zeugnis"+"/"+"2. AJ"+"/"+"Sommer" $subfolderURIs += "Zeugnis"+"/"+"3. AJ" $subfolderURIs += "Zeugnis"+"/"+"3. AJ"+"/"+"Winter" $subfolderURIs += "Zeugnis"+"/"+"3. AJ"+"/"+"Sommer" $subfolderURIs += "Klassenbesprechungen" $subfolderURIs += "Entschuldigungen Freistellungen" $rootfoldername=$global:ncParams['NCrootFolderName'] write-msg -msg "$funcName : Read hashtable classes:Teachers from Untis or file" -path_prot $global:ncParams['allgLogfile']| Out-Null $hashClassesTeachers=@{} # get credentials for Untis $WUcreds=get-LoginCreds -userKey "WUuser" -passKey "WUpass" -passFileKey "WUpassFile" $hashClassesTeachers=get-untisClassTeacherTeams -checkHashlistClassesTeachers $true -WUlocationClassTeachers $global:ncParams['WUlocationClassTeachers'] -WUclassesTeachersDelimiter $global:ncParams['WUclassesTeachersDelimiter'] -WUcreds $WUcreds # Read hashtable classes:Teachers from Untis or file write-msg -msg "$funcName : Creating list of teacher initials and Nextcloud User ID" -path_prot $global:ncParams['allgLogfile']| Out-Null $userInitial_NCid=new-NCuserIDlist # List of teacher initials and Nextcloud User ID } Process{ foreach ($class in $hashClassesTeachers.Keys){ # teachers of the class $teachers = ($hashClassesTeachers[$class] + ',' + $global:ncParams['NClistOfAdditionalSharers']).split(",") # if it doesn't already exists create New Class Folder if ($rootfoldername -eq "/"){ $itempath=$rootfoldername+$class } else{ $rootfoldername=$rootfoldername.TrimStart("/") $rootfoldername=$rootfoldername.TrimEnd("/") $itempath="/"+$rootfoldername+"/"+$class } $uri=$global:ncParams['NCuriDav']+$itempath $fileexists=test-NCpath -uri $uri if (!$fileexists) { new-NCfolder -rootFolderName $rootFolderName -newFolderName $class } else{ # compare and remove former shares/ priviliges which are no longer valid $oldUserShares=get-NCuserShares -itemPath $itempath foreach ($oldUserShare in $oldUserShares.GetEnumerator()){ $valid=$false foreach ($teacher in $teachers){ if (!$valid -and $oldUserShare.key -eq $userInitial_NCid[$teacher]){$valid=$true} } if (!$valid){ # old usershare is no longer in new teacher list: delete-NCuserShare delete-NCuserShare -itemPath $itempath -shareID $oldUserShare.value } } } # set user privileges foreach ($teacher in $teachers){ Try{ # if $teacher is not in $hashClassesTeachers this will throw an error # Untis returns non valid initials every now and then e.g. "---" set-NCuserShare -itemPath $itemPath -userID $userInitial_NCid[$teacher] } catch{ # nothing to do, leave that non valid initial out and jump to next entry write-msg -msg "$funcName : initial $teacher not valid, class: $class" -path_prot $global:ncParams['allgLogfile']| Out-Null } } # Add additional subfolders for the new classfolders if (!$fileexists) { foreach ($folder in $subfolderURIs){ # create new Subfolder write-msg -msg "$funcName : creating new subfolder: $folder" -path_prot $global:ncParams['allgLogfile']| Out-Null new-NCfolder -rootFolderName $itempath -newFolderName $folder } } } } } # end new-NCfolders # ************************************** end new-NCfolders ************************************ # # ************************************** is-Under18 ************************************ # <# .Synopsis Prüft, ob ein SoS minderjährig ist .DESCRIPTION Prüft, ob ein SoS minderjährig ist .PARAMETER dateOfBirth Geburtsdatum des SoS im Format dd.MM.yyyy .EXAMPLE is-Under18 -dateOfBirth "28.04.2004" #> function is-Under18 { [CmdletBinding()] Param ( [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)] [String]$dateOfBirth # dd.MM.yyyy Format wie aus get-BPPupils ) Begin{ $doB = [datetime]::parseexact($dateOfBirth, 'MM/dd/yyyy HH:mm:ss',$null) $now = Get-Date $dif = $now - $doB $years = [Math]::Truncate($($now - $doB).Days / 365) if ($years -lt 18){return $true} else {return $false} } } # ************************************** end is-Under18 ************************************ # <# ************************************** new-classList ************************************ # .Synopsis Erstellt eine Klassenliste mit Daten aus BBS-Planung und Active Directory des Schulnetzes .DESCRIPTION Die Funktion new-classList ist dafür konzipiert, eine Liste von Schülerdaten basierend auf verschiedenen Eingabeparametern zu erstellen. Diese Funktion nimmt Daten von Schülern, Unternehmen und Ausbildern aus BBS-Planung entgegen und verarbeitet diese, um eine detaillierte Klassenliste zu erstellen. Hier ist eine Schritt-für-Schritt-Erklärung der Funktionsweise: Im Begin-Block werden Kommentare verwendet, um die Struktur der Eingabedaten zu beschreiben. Dies umfasst Informationen wie Klassenname, Schülerdaten (z.B. Name, Geburtsdatum, Adresse), Unternehmensdaten (z.B. Name, Adresse) und Ausbilderdaten (z.B. Name, E-Mail, Telefon). Im Process-Block erfolgt die eigentliche Verarbeitung: Initialisierung der Klassenliste: Eine leere Liste wird erstellt, um die verarbeiteten Schülerdaten aufzunehmen. Selektion der Schüler der aktuellen Klasse: Durch Filterung der $bpStudents-Liste werden nur die Schüler der spezifizierten Klasse ($class) ausgewählt. Durchlaufen der Schülerliste: Für jeden Schüler in der gefilterten Liste werden folgende Schritte durchgeführt: Ein neues Objekt für den Schüler wird erstellt, mit vordefinierten Eigenschaften. Überprüfung, ob der Schüler minderjährig ist, basierend auf dem Geburtsdatum. Zuweisung der Schülerdaten zu den entsprechenden Eigenschaften des neuen Objekts. Ermittlung und Zuweisung der Ausbilder- und Unternehmensdaten, falls vorhanden. Das neue Schülerobjekt wird der Klassenliste hinzugefügt. Sortierung der Klassenliste: Die fertige Liste wird nach Nachnamen (und Vornamen) der Schüler sortiert. Rückgabewert Die sortierte Klassenliste wird als Ergebnis der Funktion zurückgegeben. .PARAMETER class Der Name der Klasse, für die die Liste erstellt wird. .PARAMETER bpStudents Eine Liste von Schülerdaten. .PARAMETER bpCompanies Eine Liste von Unternehmensdaten. .PARAMETER bpInstructors Eine Liste von Ausbilderdaten. .PARAMETER adStudents Eine Liste von Schülerdaten aus einem Active Directory, speziell für E-Mail-Adressen. .EXAMPLE new-classList -class "FISI20A" -bpStudents $bpStudents -bpCompanies $bpCompanies -bpInstructors $bpInstructors -adStudents $adStudents #> function new-classList { [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] [string]$class, [Parameter(Mandatory=$true)] [System.Collections.ArrayList]$bpStudents, [Parameter(Mandatory=$true)] [System.Collections.ArrayList]$bpCompanies, [Parameter(Mandatory=$true)] [System.Collections.ArrayList]$bpInstructors, [Parameter(Mandatory=$true)] [System.Collections.ArrayList]$adStudents ) Begin { # $bpClasses # KNAME: Klassenname # ID_LEHRER: Lehrkraftkürzel # $bpStudents # BBSID : 376 # NNAME : Müller # VNAME : Benjamin # GEBDAT : 02.02.2002 00:00:00 # GEBORT : Kneipendorf # STR : Auguststraße 42 # PLZ : 34567 # ORT : Kneipendorf # TEL : # TEL_HANDY : 0123 4567890 # FAX : EmployeeID # EMAIL : benjamin.mueller@gmx.de # GESCHLECHT : 1 # KL_NAME : FISI20A # BETRIEB_NR : 1047 (weist auf get-BPInstructors.betrieb_nr und get-BPCompanies.betrieb_nr) # ID_AUSBILDER : # E_ANREDE : # E_NNAME : Müller # E_VNAME : Mama # E_STR : Auguststraße 42 # E_PLZ : 34567 # E_ORT : Kneipendorf # E_TEL : # E_FAX : # E_EMAIL : # $bpCompanies # NAME : ABC Solutions GmbH # PLZ : 30111 # ORT : Hannover # STRASSE : Bergstr. 20 # NR : # ID : 1896 # BETRIEB_NR : 9 # $bpInstructors # BETRIEB_NR : 444 # ID_BETRIEB : 1896 (weist auf get-BPCompanies. # NNAME : Herr Goethe # EMAIL : wolfgang@goethe.com # TELEFON : 0500 54 22 000 # FAX : 0500 54 22 001 # NNAME2 : # EMAIL2 : # TELEFON2 : } Process { # Neues Klassenformular anlegen $classList = @() # SuS der aktuellen Klasse selektieren $bpStudentsOfTheClass = $bpStudents|Where-Object {$_.KL_NAME -eq $class} foreach ($bpStudent in $bpStudentsOfTheClass){ $newStudent = "" | Select-Object -Property "NNAME","VNAME","KLASSE","EMAIL","GEBDAT","MINDERJ","AUSNAME","AUSEMAIL","AUSTEL","AUSBETR","AUSSTR","AUSPLZ","AUSORT","ENNAME","EVNAME","EEMAIL","ETEL" # Für jeden SoS Daten eintragen try{ $isUnder18 = is-Under18 ($bpStudent.GEBDAT) $newStudent.GEBDAT = get-date -Date $bpStudent.GEBDAT -Format "dd.MM.yyyy" $newStudent.MINDERJ = if($isUnder18){$global:NCparams['NCtextMinderjaehrig']} else {$global:NCparams['NCtextErwachsen']} } catch {$isUnder18 = $false} # Geburtsdatum in BBS-Planung leer oder falsches Format $newStudent.NNAME = $bpStudent.NNAME $newStudent.VNAME = $bpStudent.VNAME $newStudent.KLASSE = $bpStudent.KL_NAME $newStudent.ENNAME = if($isUnder18){$bpStudent.E_NNAME} else {""} $newStudent.EVNAME = if($isUnder18){$bpStudent.E_VNAME} else {""} $newStudent.EEMAIL = if($isUnder18){$bpStudent.E_EMAIL} else {""} $newStudent.ETEL = if($isUnder18){$bpStudent.E_TEL} else {""} $newStudent.EMAIL = ($adStudents|Where-Object{$_.EmployeeID -eq $bpStudent.FAX}).Mail # Ausbilder/ Betrieb ermitteln und eintragen if ($bpStudent.BETRIEB_NR -ne ""){ $instructor = ($bpInstructors|where-Object{$_.BETRIEB_NR -eq $bpStudent.BETRIEB_NR}) $company = ($bpCompanies|where-Object{$_.BETRIEB_NR -eq $bpStudent.BETRIEB_NR}) $newStudent.AUSNAME = $instructor.NNAME $newStudent.AUSEMAIL = $instructor.EMAIL $newStudent.AUSTEL = $instructor.TELEFON $newStudent.AUSBETR = $company.NAME $newStudent.AUSSTR = $company.STRASSE $newStudent.AUSPLZ = $company.PLZ $newStudent.AUSORT = $company.ORT } else{ $newStudent.AUSNAME = "" $newStudent.AUSEMAIL = "" $newStudent.AUSTEL = "" $newStudent.AUSBETR = "" $newStudent.AUSSTR = "" $newStudent.AUSPLZ = "" $newStudent.AUSORT = "" } # Ende Daten eines SoS eintragen $classList += $newStudent } # Ende Daten aller SoS einer Klasse eintragen # Klassenliste nach Nachnamen sortieren ### ---- Klassenliste mit Lernenden gefüllt ----#### return ($classList|sort-object -Property @{Expression="NNAME"}, @{Expression="VNAME"}) } # Ende Daten einer Klasse eintragen } # ************************************** end new-classList ************************************ # # ************************************** new-NCclassLists ************************************ # <# .Synopsis Erstellt csv-Listen, ähnlich wie Klassenlisten mit E-mail in BBS Planung und legt sie in der Nextcloudstruktur der Klasse ab .DESCRIPTION Erstellt csv-Listen, ähnlich wie Klassenlisten mit E-Mail in BBS Planung und legt sie in der Nextcloudstruktur der Klasse ab Sollte eine Datei ($global:ncParams['LDAPsusFilePath'] mit SuS-LDAP-Daten vorhanden sein, wird diese genutzt anstelle einer LDAP-Abfrage .EXAMPLE new-NCclassLists #> function new-NCclassLists{ [CmdletBinding()] Param ( [Parameter(Mandatory=$false)] [boolean] $sendEMailToTeachers=$false ) Begin { # # Das Skript läuft auf dem Terminalserver im Verwaltungsnetz, da dort die Anbindung an BBS-Planung möglich ist $funcName = $MyInvocation.InvocationName $pathOldLists = $global:NCparams['NCpathOldClassLists'] $pathNewLists = $global:NCparams['NCpathNewClassLists'] $csvDelimiter = $global:NCparams['allgCsvDelimiter'] # Alle Daten besorgen $timeStamp = write-msg -msg "$funcName : Lese Klassenliste ein..." -path_prot $global:ncParams['allgLogfile'] $bpClasses = get-BPcourses -useDB $false -bpBackupRootDir $global:NCparams['BPBackupRootDir'] write-msg -msg "$funcName : Klassenliste eingelesen" -time $timeStamp -path_prot $global:ncParams['allgLogfile'] $timeStamp = write-msg -msg ("$funcName : Lese Schülerliste ein...") -path_prot $global:ncParams['allgLogfile'] $bpStudents = get-BPPupils -useDB $false -bpBackupRootDir $global:NCparams['BPBackupRootDir'] write-msg -msg ("$funcName : Schülerliste eingelesen") -time $timeStamp $timeStamp = write-msg -msg ("$funcName : Lese Betriebsliste ein...") $bpCompanies = Get-BPCompanies -useDB $false -bpBackupRootDir $global:NCparams['BPBackupRootDir'] write-msg -msg ("$funcName : Betriebsliste eingelesen") -time $timeStamp -path_prot $global:ncParams['allgLogfile'] $timeStamp = write-msg -msg ("$funcName : Lese Lehrkräfteliste ein...") $bpInstructors = Get-BPinstructors -useDB $false -bpBackupRootDir $global:NCparams['BPBackupRootDir'] write-msg -msg ("$funcName : Lehrkräfteliste eingelesen") -time $timeStamp -path_prot $global:ncParams['allgLogfile'] # Get credentials for LDAP access school network $ldapCreds=(get-LoginCreds -userKey "LDAPuserName" -passKey "LDAPuserPass" -passFileKey "LDAPuserCredsFile") # Daten der Lernenden aus AD lesen if((Test-Path $global:NCparams['LDAPsusFilePath']) -and ((Get-Item $($global:NCparams['LDAPsusFilePath'])).LastWriteTime.Date -eq (Get-Date).Date)){ # Daten aus vorheriger Abfrage auslesen, falls diese vorhanden sind UND TAGESAKTUELL (geht schneller) write-msg -msg "$funcname : Lese LDAP-Daten der Lernenden aus Datei $($global:NCparams['LDAPsusFilePath']) aus..." -path_prot $global:ncParams['allgLogfile']| Out-Null $adStudents=Import-csv -Path $global:NCparams['LDAPsusFilePath'] -Encoding utf8 -Delimiter $global:NCparams['allgCsvDelimiter'] } else { # Keine gespeicherten Daten vorhanden Try{ $timeStamp = write-msg -msg "$funcname : Hole LDAP-Daten der Lernenden von $($global:NCparams['LDAPmm-bbsURI'])..." -path_prot $global:ncParams['allgLogfile'] $adStudents=Get-ADUser -Server $global:NCparams['LDAPmm-bbsURI'] -Credential $ldapCreds -Properties EmployeeID,Surname,GivenName,Mail,DistinguishedName -Filter {(Name -like "*")} -SearchBase "OU=Schueler,DC=int,DC=mm-bbs,DC=de" write-msg -msg "$funcname : LDAP-Daten der Lernenden geholt" -time $timeStamp -path_prot $global:ncParams['allgLogfile'] # EmployeeID ist das Attribut Faxnummer, also unser Primärschlüssel in BBS-Planung etc. # für nächsten Durchlauf speichern $adStudents|export-csv -Path $global:NCparams['LDAPsusFilePath'] -Encoding UTF8 -NoTypeInformation -Delimiter $global:NCparams['allgCsvDelimiter'] write-msg -msg "$funcname : LDAP-Daten der Lernenden in Datei $($global:NCparams['LDAPsusFilePath']) gespeichert" -path_prot $global:ncParams['allgLogfile']| Out-Null } catch{ write-msg -msg "$funcName : Error access to LDAP server $($error)" -path_prot $global:ncParams['allgLogfile']| Out-Null $error.clear() } } # Daten der Lehrkräfte aus AD lesen if((Test-Path $global:NCparams['LDAPlulFilePath']) -and ((Get-Item $($global:NCparams['LDAPlulFilePath'])).LastWriteTime.Date -eq (Get-Date).Date)){ # Daten aus vorheriger Abfrage auslesen, falls diese vorhanden sind UND TAGESAKTUELL (geht schneller) write-msg -msg "$funcname : Lese LDAP-Daten der Lehrkräfte aus Datei $($global:NCparams['LDAPlulFilePath']) aus..." -path_prot $global:ncParams['allgLogfile']| Out-Null $adTeachers=Import-csv -Path $global:NCparams['LDAPlulFilePath'] -Encoding utf8 -Delimiter $global:NCparams['allgCsvDelimiter'] } else { # Keine gespeicherten Daten vorhanden Try{ $timeStamp = write-msg -msg "$funcname : Hole LDAP-Daten der Lehrkräfte von $($global:NCparams['LDAPmm-bbsURI'])..." -path_prot $global:ncParams['allgLogfile'] $adTeachers=Get-ADUser -Server $global:NCparams['LDAPmm-bbsURI'] -Credential $ldapCreds -Properties Initials,Surname,GivenName,Mail,DistinguishedName -Filter {(Name -like "*")} -SearchBase "OU=Lehrer,DC=int,DC=mm-bbs,DC=de" # Initials ist das Lehrkraftkürzel, also unser Primärschlüssel in BBS-Planung etc. # für nächsten Durchlauf speichern $adTeachers|export-csv -Path $global:NCparams['LDAPlulFilePath'] -Encoding UTF8 -NoTypeInformation -Delimiter $global:NCparams['allgCsvDelimiter'] write-msg -msg "$funcname : LDAP-Daten der Lehrkräfte in Datei $($global:NCparams['LDAPlulFilePath']) gespeichert" -time $timeStamp -path_prot $global:ncParams['allgLogfile'] } catch{ write-msg -msg "$funcName : Error access to LDAP server" -path_prot $global:ncParams['allgLogfile']| Out-Null $error.clear() } } # Bei Bedarf Klassenordner anlegen if (!(test-path $pathOldLists)){New-Item -Path $pathOldLists -ItemType Directory} if (!(test-path $pathNewLists)){New-Item -Path $pathNewLists -ItemType Directory} } Process{ foreach ( $class in $bpClasses){ write-msg -msg ("$funcName : Erzeuge Klassenliste $($class.KNAME)...") -path_prot $global:ncParams['allgLogfile']| Out-Null $classList = new-classList -class $class.KNAME -bpStudents $bpStudents -bpCompanies $bpCompanies -bpInstructors $bpInstructors -adStudents $adStudents # csv Datei schreiben $classList|export-csv -path "$pathNewLists\$($class.KNAME).csv" -encoding UTF8 -delimiter $csvDelimiter -noTypeInformation $replaceClassList = $false # Falls alte Klassenliste vorhanden, prüfen, ob neue Liste Änderungen aufweist if (test-path "$pathOldLists\$($class.KNAME).csv"){ # alte Liste vorhanden $oldListContent = Get-Content -Path "$pathOldLists\$($class.KNAME).csv" $newListContent = Get-Content -Path "$pathNewLists\$($class.KNAME).csv" # Vergleichen nur, wenn Länge gleich ist if ($oldListContent.count -eq $newListContent.count){ $len=$newListContent.count # Inhalt zeilenweise vergleichen for ($idx=0;($idx -lt $len) -and (!$replaceClassList); $idx+=1){ if ($oldListContent[$idx] -ne $newListContent[$idx]){ $replaceClassList = $true # aktuelle Zeilen in beiden Listen unterschiedlich } } } else {$replaceClassList = $true} # Länge der alten und neuen Liste unterschiedlich } else {$replaceClassList = $true} # Alte Klassenliste nicht vorhanden, also ganz neu anlegen if ($replaceClassList){ # Liste ersetzen, neue Liste zu alten Listen hinzufügen/ alte Liste überschreiben copy-Item -path "$pathNewLists\$($class.KNAME).csv" -destination "$pathOldLists\$($class.KNAME).csv" -force # Neue Liste in Nextcloud speichern upload-NCfile -sourceFileUri "$pathNewLists\$($class.KNAME).csv" -destRootFolder "$($global:NCparams['NCrootFolderName'])/$($class.KNAME)/$($global:NCParams['NCsusListenFolderName'])" -destFile "$($class.KNAME).csv" -overwrite $true write-msg -msg "$funcname : $($class.KNAME).csv in Nextcloud geladen" -path_prot $global:ncParams['allgLogfile']| Out-Null if ($sendEMailToTeachers){ # Pushnachricht Klassenlehrkräfte (evtl. mit detaillierten Änderungen, dann oben compare-object verwenden anstatt hashvergleich) # Get all teachers of the class, Parameter true sorgt für das Lesen einer gespeicherten, tagesaktuellen Version der Hashtabelle, falls vorhanden (geht schneller) # get credentials for Untis $WUcreds=get-LoginCreds -userKey "WUuser" -passKey "WUpass" -passFileKey "WUpassFile" $hashClassesTeachers=get-untisClassTeacherTeams -checkHashlistClassesTeachers $true -WUlocationClassTeachers $global:ncParams['WUlocationClassTeachers'] -WUclassesTeachersDelimiter $global:ncParams['WUclassesTeachersDelimiter'] -WUcreds $WUcreds # # Lehrkräfte der aktuellen Klasse ermitteln $classTeachers = @() $classTeachers = ($hashClassesTeachers[$class.KNAME]).split($global:ncParams.WUclassesTeachersDelimiter) # E-Mailadressen der LuL ermitteln, Lehrkäftedaten aus AD stehen in $adTeachers $classTeachersEmail = @() foreach ($teacher in $classTeachers){ $mail=""|select-object -Property email, initial, GivenName, Name $mail.email = ($adTeachers|Where-Object{$_.Initials -eq $teacher}).Mail $mail.initial = $teacher $mail.GivenName = ($adTeachers|Where-Object{$_.Initials -eq $teacher}).GivenName $mail.Name = ($adTeachers|Where-Object{$_.Initials -eq $teacher}).Name if ($mail.email -ne $null) {$classTeachersEmail += $mail} } # Get credentials for EMAIL access $EMAILpw = ConvertFrom-SecureString -SecureString (get-LoginCreds -userKey "EMAILadminUser" -passKey "EMAILadminPass" -passFileKey "EMAILpassFile").Password -AsPlainText $timeStamp = get-date write-msg -msg "$funcname : Schreibe E-Mails an Lehrkräfte ..." -path_prot $global:ncParams['allgLogfile']| Out-Null $emailcreds = get-LoginCreds -userKey "EMAILadminUser" -passKey "EMAILadminPass" -passFileKey "EMAILpassFile" $emailbody="" foreach ($to in $classTeachersEmail) { $emailSubject = $global:ncParams.EMAILsubject $emailSubject=$emailSubject.Replace("<Klasse>", $class.KNAME) $emailbody=$null $emailbody=(Get-Content -path $global:ncParams.EMAILbodyFile) -join "`n" $emailbody=$emailbody.Replace("<Vorname>",$to.GivenName) $emailbody=$emailbody.Replace("<Nachname>",$to.Name) $emailbody=$emailbody.Replace("<Klasse>",$class.KNAME) $recipient = $to.email $sender = $global:ncparams.EMAILsender Send-MailMessage -Credential $emailcreds -to $recipient -from $sender -SmtpServer $global:ncParams.EMAILserver -Port $global:ncParams.EMAILport -Encoding UTF8 -Subject $emailSubject -body $emailBody -BodyAsHtml } write-msg -msg "$funcname : E-Mails an Lehrkräfte der Klasse $($class.KNAME) verschickt!" -path_prot $global:ncParams['allgLogfile']| Out-Null } # Ende E-Mail an Lehrkräfte } # Ende Liste ersetzen } # Ende mit alle Klassenlisten erstellen } # end Process } # ************************************** end new-NCclassLists ************************************ # # ************************************** end nextcloudVWNManager ************************************ # <# Alle Funktionen in diesem Modul get-NCparameters get-LoginCreds new-NCfolder set-NCuserShare get-NCuserShares delete-NCuserShare new-NCuserIDlist test-NCpath upload-NCfile new-NCfolders is-Under18 new-classList new-NCclassLists #> |