Powershell/Opcon/Daily Jobs To Html/DailyJobsToHtml.ps1
2023-07-04 12:59:44 +02:00

525 lines
21 KiB
PowerShell

#############
#
# 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 = "
<tr>
<td>$($DateStr) </td>
<td>$($job.schedule.name) </td>
<td> </td>
<td>$($job.name)</td>
<td>$($job.primaryMachine.name)</td>
<td>$($job.jobType.description)</td>
<td $($htmlCellStyle)>$($job.status.description)</td>
<td>$($StartTimeProgrammed)</td>
<td>$($EndTimeProgrammed)</td>
<td $($htmlCellStyleStartRetard)>$($StartTimeTime) $($StartTimeTimeEstimated)</td>
<td $($htmlCellStyleEndRetard)>$($EndTimeTime) $($EndTimeTimeEstimated)</td>
<td>$($job.computedDuration.duration/1000/60) $($DurationEstimated)</td>
</tr>"
$FinalData += $DataRow
$jobSearch = $job.schedule.name+"|"+$job.name
$ListSousJob = HistoryJobDay -Dates $Dates -JobName $jobSearch
If ($ListSousJob.Count -ne 0) {
Foreach($SousJob in ($ListSousJob|Select -skip 1)) {
$SousStartTimeTime =TryParseDate -inDate $SousJob.jobStartTime -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz'
$SousEndTimeTime = TryParseDate -inDate $SousJob.jobTermination -format 'yyyy-MM-ddTHH:mm:ss.fffffffzzz'
If ($SousJob.jobstatus.description -Contains "Failed") {
$htmlCellStyle = "style='background:#FF0000'"
$RowsFailed = $RowsFailed + 1
}
ElseIf ($SousJob.jobstatus.description -Contains "Skipped") {
$htmlCellStyle = "style='background:#F000FF'"
$RowsSkipped = $RowsSkipped + 1
}
ElseIf ($SousJob.jobstatus.description -Contains "Cancelled") {
$htmlCellStyle = "style='background:#0017FF'"
$RowsCancelled = $RowsCancelled + 1
}
ElseIf ($SousJob.jobstatus.description -Contains "Job Running") {
$htmlCellStyle = "style='background:#000000;color:white'"
$RowsRun = $RowsRun + 1
}
Else {
$RowsOK = $RowsOK + 1
}
$DataRow = "
<tr>
<td>$($DateStr) </td>
<td>$($job.schedule.name) </td>
<td><img src='./media/horloge.png' width='10' height='10'></td>
<td>$($job.name)</td>
<td>$($job.primaryMachine.name)</td>
<td>$($job.jobType.description)</td>
<td $($htmlCellStyle)>$($SousJob.jobstatus.description)</td>
<td>$($StartTimeProgrammed)</td>
<td>$($EndTimeProgrammed)</td>
<td $($htmlCellStyleStartRetard)>$($SousStartTimeTime)</td>
<td $($htmlCellStyleEndRetard)>$($SousEndTimeTime)</td>
<td>$($SousJob.Duration/1000/60)</td>
</tr>"
$FinalData += $DataRow
[int]$Rows = [int]$Rows + 1
[int]$Total = [int]$Total + 1
}
}
}
(Get-Content -path HtmlTemplate.html -Raw) -replace 'ROWS_PLACE_HOLDER',$FinalData | Out-File -FilePath Rapport-$OpScheduleDate-tmp-01.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-01.html -Raw) -replace 'ROWS_OK_NUMBER',$RowsOK | Out-File -FilePath Rapport-$OpScheduleDate-tmp-02.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-02.html -Raw) -replace 'ROWS_SKIPPED_NUMBER',$RowsSkipped | Out-File -FilePath Rapport-$OpScheduleDate-tmp-03.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-03.html -Raw) -replace 'ROWS_CANCELLED_NUMBER',$RowsCancelled | Out-File -FilePath Rapport-$OpScheduleDate-tmp-04.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-04.html -Raw) -replace 'ROWS_FAILED_NUMBER',$RowsFailed | Out-File -FilePath Rapport-$OpScheduleDate-tmp-05.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-05.html -Raw) -replace 'ROWS_RUN_NUMBER',$RowsRun | Out-File -FilePath Rapport-$OpScheduleDate-tmp-06.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-06.html -Raw) -replace 'ROWS_NUMBER',$Rows | Out-File -FilePath Rapport-$OpScheduleDate-tmp-07.html
$Percentage_Ok = ($RowsOK * 100 ) / $Rows
$Percentage_Skipped = ($RowsSkipped * 100 ) / $Rows
$Percentage_Cancelled = ($RowsCancelled * 100 ) / $Rows
$Percentage_Failed = ($RowsFailed * 100 ) / $Rows
$Percentage_Run = ($RowsRun * 100 ) / $Rows
(Get-Content -path Rapport-$OpScheduleDate-tmp-07.html -Raw) -replace 'PERCENTAGE_OK_NUMBER',$Percentage_Ok | Out-File -FilePath Rapport-$OpScheduleDate-tmp-08.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-08.html -Raw) -replace 'PERCENTAGE_SKIPPED_NUMBER',$Percentage_Skipped | Out-File -FilePath Rapport-$OpScheduleDate-tmp-09.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-09.html -Raw) -replace 'PERCENTAGE_CANCELLED_NUMBER',$Percentage_Cancelled | Out-File -FilePath Rapport-$OpScheduleDate-tmp-10.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-10.html -Raw) -replace 'PERCENTAGE_FAILED_NUMBER',$Percentage_Failed | Out-File -FilePath Rapport-$OpScheduleDate-tmp-11.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-11.html -Raw) -replace 'PERCENTAGE_RUN_NUMBER',$Percentage_Run | Out-File -FilePath Rapport-$OpScheduleDate-tmp-12.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-12.html -Raw) -replace 'ROWS_START_Retard',$RowsStartRetard | Out-File -FilePath Rapport-$OpScheduleDate-tmp-13.html
(Get-Content -path Rapport-$OpScheduleDate-tmp-13.html -Raw) -replace 'ROWS_END_Retard',$RowsEndRetard | Out-File -FilePath Rapport-$OpScheduleDate.html
Remove-Item Rapport-$OpScheduleDate-tmp-*.html -Force -Confirm:$False
}
#
$SecPass = $null;
$clearPassword = ""
If ($OpConPassword.Length -eq 0 ) {
$SecPass = Read-Host 'Quel est le mot de passe ?' -AsSecureString
$clearPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecPass))
}
Else {
$clearPassword = $OpConPassword
}
Login-RestApi -ApiUrl $ServerUrl -OpConUser $OpConUser -OpConPassword $clearPassword
DisplayDailyJobs -Status $OpJobStatus -Dates $OpScheduleDate -JobType ""
Invoke-Item .\Rapport-$OpScheduleDate.html