############# # # Auteur : Hubert Cornet # date : 13 avril 2022 # # description du script : intérroge l'API d'OPCON # ############# # Variable et argment dans le lancement du script Param( [string] $OpScheduleDate = "", [string] $OpJobStatus = "", [string] $OpConUser = "ocadm", [string] $OpConPassword, [string] $ServerUrl = "https://10.78.56.27:443" ) clear # Fonction Function Ignore-SelfSignedCerts { add-type -TypeDefinition @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy } # Function Invoke-OpConRestMethod { Param( [ValidateNotNullorEmpty()] [String]$Uri, [ValidateNotNullorEmpty()] [String]$Method, [object]$Body = $null ) If (!$Global:OpconRESTApiUrl -or !$Global:OpconRESTApiAuthHeader) { Write-Warning "No values for Opcon REST Api. Please use Logon-OpConApi before using cmdlet." throw [System.Exception] "Invalid OpCon REST API Values" } $uri = $Global:OpconRESTApiUrl + $Uri Write-Verbose ("Envoi de la requete Web ...") Try { If ($Body -eq $null) { $response = Invoke-RestMethod -Method $Method -Uri $uri -Headers $Global:OpconRESTApiAuthHeader -ErrorVariable $RestException } Else { $Body = ConvertTo-Json $Body -Depth 99 $response = Invoke-RestMethod -Method $Method -Uri $uri -Headers $Global:OpconRESTApiAuthHeader -Body $Body -ContentType 'application/json; charset=utf-8' -ErrorVariable $RestException } Write-Verbose ("`n") Write-Verbose("RESPONSE :") Write-Verbose(ConvertTo-Json $response -Depth 9) return $response } Catch { Write-Warning ("Erreur") Write-Warning ("Status Code : " + $_.Exception.Response.StatusCode.value__) Write-Warning ("Status Description : " + $_.Exception.Response.StatusDescription) $opconApiError = ConvertFrom-Json $_.ErrorDetails.Message Write-Warning ("Erreur Code : " + $opconApiError.code) Write-Warning ("Erreur Message : " + $opconApiError.message) throw ##exit $_.Exception.Response.StatusCode.value__ } } # Function Get-OpConApiToken { [cmdletbinding()] Param( [string] $Url, [string] $User, [string] $Password ) $tokensUri = -join($Url, "/api/tokens") Write-Host ("Recuperation du token autorisation ...") Write-Host ("Api: " + $tokensUri) Write-Host ("Utilisateur: " + $User) $tokenObject = @{ user = @{ loginName = $User password = $Password } tokenType = @{ type = "User" } } Try { Ignore-SelfSignedCerts $token = Invoke-RestMethod -Method Post -Uri $tokensUri -Body (ConvertTo-Json $tokenObject) -ContentType 'application/json; charset=utf-8' -ErrorVariable $RestException } Catch { ## $error = ConvertFrom-Json $RestException.ErrorDetails.Message ##Write-Host ("Unable to fetch token for user '" + $user + "'") ##Write-Host ("Error Code: " + $error.code) ##Write-Host ("Message: " + $error.message) Write-Host ("Status Code : " + $_.Exception.Response.StatusCode.value__) Write-Host ("Status Description : " + $_.Exception.Response.StatusDescription) Write-Host ("Message : " + $_[0].message) ##$Global:OpConRESTAPIException = $_ throw ##exit $_.Exception.Response.StatusCode.value__ } Write-Host ("Token recu avec succes, Id : " + $token.id + ", Valide jusqu a : " + $token.validUntil) return $token } # Function Get-OpConApiAuthHeader { Param( [string] $Token ) $authHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $authHeader.Add("Authorization", ("Token " + $Token)) return $authHeader } # Function Login-RestApi { [cmdletbinding()] Param( [string] $ApiUrl, [string] $OpConUser, [string] $OpConPassword ) Write-Verbose ("Parametres =") Write-Verbose ("ApiUrl: " + $ApiUrl) Write-Verbose ("OpConUser: " + $OpConUser) Write-Verbose ("OpConPassword: (hidden)") $ApiUrl = $ApiUrl.ToLower().TrimEnd("/").TrimEnd("/api") Write-Host ("Connexion a OPCON REST API: " + $ApiUrl) $Global:OpconRESTApiUrl = $ApiUrl $Global:OpconRESTApiUser = $OpConUser $Global:OpConRESTApiPassword = $OpConPassword $token = Get-OpConApiToken -Url $ApiUrl -User $OpConUser -Password $OpConPassword $Global:OpconRESTApiToken = $token.id $Global:OpconRESTApiAuthHeader = Get-OpConApiAuthHeader -Token $token.id Write-Host ('Token stocke avec succes pour de futurs appels dans la session.') } Function HistoryJobDay { [cmdletbinding()] Param( [string] $Dates, [string] $JobName ) $JobDayListFull = New-Object System.Collections.Generic.List[System.Object] Try { #$JobName = "PlanDeProdRéel_C1-60MinutesAprèsMidi_CNT[C1-SS-FR-FluxAX_DHB_AttARV_Prod]|C2-DHB_DAX_DHB_REF_OFR_ART_CFG-STB-DHB" #$JobName = "" #$Dates = "2022-04-20" #$jobNameParam = [System.Web.HttpUtility]::UrlEncode($jobName) $jobUri = -join("/api/jobhistories?uniqueJobIds=$jobName&from=$Dates&to=$Dates") #write-host "1 " $jobUri $uri = $Global:OpconRESTApiUrl + $jobUri #write-host "2 " $uri #$jobdayResponse = Invoke-OpConRestMethod -Uri $jobUri -Method GET -ContentType "application/json"-Headers $Global:OpconRESTApiAuthHeader -ErrorVariable $RestException; $jobdayResponse = Invoke-RestMethod -Method GET -Uri $uri -Headers $Global:OpconRESTApiAuthHeader -ContentType 'application/json' -ErrorVariable $RestException #write-host "3 " $jobdayResponse.id #https://10.78.56.27/api/jobhistories?uniqueJobIds=$JobName&from=$Dates&to=$Dates #https://10.78.56.27/api/jobhistories?uniqueJobIds=PlanDeProdR%C3%A9el_C1-60MinutesApr%C3%A8sMidi_CNT%5BC1-SS-FR-FluxAX_DHB_AttARV_Prod%5D%7CC1-DHB_DAX_DHB_DAX_DHB_CMC_SUV_LIG_CDE_CLI-STB-DHB&from=2022-04-13&to=2022-04-13 #https://10.78.56.27/api/jobhistories?uniqueJobIds=PlanDeProdRéel_C1-60MinutesAprèsMidi_CNT[C1-SS-FR-FluxAX_DHB_AttARV_Prod]|C1-DHB_DAX_DHB_DAX_DHB_CMC_SUV_LIG_CDE_CLI-STB-DHB&from=2022-04-13&to=2022-04-13 #https://10.78.56.27/api/jobhistories?uniqueJobIds=C9-SC-GRP-EXP-ReportingOpcon_C9-ExtractionDesCommandesAvecUneLivraisonEnJPlus1-CNT-EXP[C9-SS-FR-TSM-EXP-ExtractionCommandJPlus1]|C9-ArchiveExtraction-SQL-EXP&from=2022-04-13&to=2022-04-13 If (($jobdayResponse.Length -Ne 1) -And ($jobdayResponse.Length -Ne 0)) { Foreach($JobDay in $JobDayResponse) { #write-host $JobDay #$entry= "$($JobDay.schedule.name) - $($JobDay.id)" $JobDayListFull.Add($JobDay) #$JobDayListFull.Add(@{id = $JobDay.id}) #Write-Host ("Job name : $($JobDay.id)") } $sizeDay = $jobdayResponse.Length; $JobDayListFullsize = $JobDayListFull.Count Write-Host ("Partiel/Total nombre de job recuperer : $sizeDay/$JobDayListFullsize") } } Catch [Exception] { write-host $_ write-host $_.Exception.Message } return, $JobDayListFull } Function GetJobListToUpdateInTrances { [cmdletbinding()] Param( [string] $Status, [string] $Dates, [string] $JobType ) $offset =0; # start from $size=0; # number of jobs retrieved each call $limit=5000; # max number of record x trance $jobListFull = New-Object System.Collections.Generic.List[System.Object] Write-Host ("===> Commence a recuperer des jobs dans la limite de $limit ") Do{ $jobUri = -join("/api/dailyJobs/?dates=$Dates&scheduleIds=$($daily.id)&status=$Status&jobType=$JobType&limit=$limit&offset=$offset") #$jobUri = -join($Url, "/api/dailyJobs/?dates=$Dates&scheduleIds=$($daily.id)&status=$Status&jobType=$JobType&limit=$limit&offset=$offset") #$jobUri = -join($Url, "/api/dailyJobs/?dates=$Dates&scheduleIds=$($daily.id)&jobType=$JobType&limit=$limit&offset=$offset") $jobResponse = Invoke-OpConRestMethod -Uri $jobUri -Method GET -ContentType "application/json"-Headers $Global:OpconRESTApiAuthHeader -ErrorVariable $RestException; #Write-Host ("Job URI : $($jobUri)") Foreach($job in $jobResponse) { #$entry= "$($job.schedule.name) - $($job.id)" $jobListFull.Add($job) #$jobListFull.Add(@{id = $job.id}) #Write-Host ("Job name : $($job.id)") } $size = $jobResponse.Length; $jobListFullsize = $jobListFull.Count Write-Host ("Partiel/Total nombre recuperer : $size/$jobListFullsize") $offset+=$limit; If ($size -lt $limit) { $size = 0; } # If is necessary a delay between calls uncomment and tune the line below # Start-Sleep -s 5 }While ($size -gt 0) If ($jobListFull.Count -gt 0) { Write-host ("Jobs total recuperer : $($jobListFull.Count)") } return, $jobListFull } # Function TryParseDate { [cmdletbinding()] Param( [object] $inDate, [string] $format ) $outDate = "" Try { $outDate =[datetime]::parseexact($($inDate), $($format),$null) } Catch { $outDate = "?" } return $outDate } # Function DisplayDailyJobs { [cmdletbinding()] Param( [string] $Status, [string] $Action, [string] $Dates, [string] $JobType ) [int]$Rows = 0 [int]$RowsOK = 0 [int]$RowsCancelled = 0 [int]$RowsSkipped = 0 [int]$RowsFailed = 0 [int]$RowsRun = 0 [int]$Percentage_Ok = 0 [int]$Percentage_Skipped = 0 [int]$Percentage_Cancelled = 0 [int]$Percentage_Failed = 0 [int]$Percentage_Run = 0 [int]$RowsStartRetard = 0 [int]$RowsEndRetard = 0 #Get job list to update in trances $jobList = GetJobListToUpdateInTrances -Status $Status -Dates $Dates -JobType $JobType #$lst = jobList.chunked(3) [int]$Total = $jobList.Count Foreach($job in $jobList) { [int]$Rows = [int]$Rows + 1 [int]$Pourcentage =[int]$Rows * 100 / [int]$Total Write-Progress -Activity "Analyse du contenu OPCON pour la journée $Dates" -Status "Job : $Rows sur $Total :" -PercentComplete $Pourcentage #$dt = [datetime]::parseexact($($job.schedule.date), 'yyyy-MM-ddTHH:mm:ss.fffffffzzz',$null) $dt = TryParseDate -inDate $job.schedule.date -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz' $StartTimeProgrammed = TryParseDate -inDate $job.computedStartTime.ProgrammedFor -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz' $StartTimeTime =TryParseDate -inDate $job.computedStartTime.time -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz' $StartTimeTimeEstimated = "" If ($job.computedStartTime.isEstimated -contains "True") { $StartTimeTimeEstimated = "*" } $EndTimeProgrammed = TryParseDate -inDate $job.computedEndTime.ProgrammedFor -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz' $EndTimeTime = TryParseDate -inDate $job.computedEndTime.time -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz' $EndTimeTimeEstimated = "" If ($job.computedEndTime.isEstimated -contains "True") { $EndTimeTimeEstimated = "*" } $DurationEstimated = "" If ($job.computedDuration.isEstimated -contains "True") { $DurationEstimated = "*" } $DateStr = $dt.ToString("dd/MM/yyyy") $htmlCellStyle = "" If ($job.status.description -Contains "Failed") { $htmlCellStyle = "style='background:#FF0000'" $RowsFailed = $RowsFailed + 1 } ElseIf ($job.status.description -Contains "Skipped") { $htmlCellStyle = "style='background:#F000FF'" $RowsSkipped = $RowsSkipped + 1 } ElseIf ($job.status.description -Contains "Cancelled") { $htmlCellStyle = "style='background:#0017FF'" $RowsCancelled = $RowsCancelled + 1 } ElseIf ($job.status.description -Contains "Job Running") { $htmlCellStyle = "style='background:#000000;color:white'" $RowsRun = $RowsRun + 1 } Else { $RowsOK = $RowsOK + 1 } $htmlCellStyleStartRetard = "" $htmlCellStyleEndRetard = "" If ($job.status.description -NotContains "Skipped") { If ($StartTimeTime -NotContains "?") { $RetardStart = New-TimeSpan -start $StartTimeTime -End $StartTimeProgrammed $RetardEnd = New-TimeSpan -start $EndTimeTime -End $EndTimeProgrammed $htmlCellStyleStartRetard = "" If ($RetardStart.TotalMinutes -lt 0 ) { $htmlCellStyleStartRetard = "style='background:#C3D50F'" } ElseIf ($RetardStart.TotalMinutes -eq 0 ) { $htmlCellStyleStartRetard = "" } ElseIf ($RetardStart.TotalMinutes -gt 0 ) { $htmlCellStyleStartRetard = "style='background:#0FD536'" $RowsStartRetard = $RowsStartRetard + 1 } Else { $htmlCellStyleStartRetard = "" } $htmlCellStyleEndRetard = "" If ($RetardEnd.TotalMinutes -lt 0 ) { $htmlCellStyleEndRetard = "style='background:#C3D50F'" } ElseIf ($RetardEnd.TotalMinutes -eq 0 ) { $htmlCellStyleEndRetard = "" } ElseIf ($RetardEnd.TotalMinutes -gt 0 ) { $htmlCellStyleEndRetard = "style='background:#0FD536'" $RowsEndRetard = $RowsEndRetard + 1 } Else { $htmlCellStyleEndRetard = "" } } } $DataRow = "