Public/Test-OSDAppRepository.ps1
|
function Test-OSDAppRepository { [CmdletBinding()] param( [Parameter(Mandatory, Position=0)] [string]$RepositoryPath ) $resolvedRepository = (Resolve-Path -LiteralPath $RepositoryPath -ErrorAction Stop).Path $catalog = Get-OSDAppRepositoryManifest -RepositoryPath $resolvedRepository $driveRoot = [IO.Path]::GetPathRoot($resolvedRepository) $repositoryFreeSpaceGB = $null try { $drive = Get-PSDrive -Name $driveRoot.TrimEnd('\').TrimEnd(':') -ErrorAction Stop $repositoryFreeSpaceGB = [math]::Round($drive.Free / 1GB, 2) } catch { } $allRefs = @() foreach ($application in @($catalog.Applications)) { foreach ($packageRef in @($application.Packages)) { $allRefs += [pscustomobject]@{ Id = [string]$application.Id Architecture = [string]$packageRef.Architecture Manifest = [string]$packageRef.Manifest } } } $duplicateKeys = @( $allRefs | Group-Object { "$($_.Id.ToLowerInvariant())|$($_.Architecture.ToLowerInvariant())" } | Where-Object Count -gt 1 | Select-Object -ExpandProperty Name ) $referencedManifestPaths = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($application in @($catalog.Applications)) { foreach ($packageRef in @($application.Packages)) { $manifestPath = Join-Path $resolvedRepository ($packageRef.Manifest -replace '/', [IO.Path]::DirectorySeparatorChar) $fullManifestPath = [IO.Path]::GetFullPath($manifestPath) [void]$referencedManifestPaths.Add($fullManifestPath) $manifestExists = Test-Path -LiteralPath $manifestPath -PathType Leaf $duplicateReference = ("$(([string]$application.Id).ToLowerInvariant())|$(([string]$packageRef.Architecture).ToLowerInvariant())") -in $duplicateKeys if (-not $manifestExists) { [pscustomobject]@{ PSTypeName = 'OSDApps.RepositoryValidation' Id = $application.Id Version = $null Architecture = $packageRef.Architecture ManifestExists = $false PackageExists = $false HashValid = $false PackageValid = $false ArchitectureValid = $false IdValid = $false SuccessCodesValid = $false ArchiveDefinitionValid= $false DuplicateReference = $duplicateReference Orphaned = $false SizeMB = $null RepositoryFreeSpaceGB = $repositoryFreeSpaceGB Valid = $false } continue } $manifest = Get-Content -LiteralPath $manifestPath -Raw -Encoding UTF8 | ConvertFrom-Json $packagePath = Join-Path (Split-Path -Path $manifestPath -Parent) 'Package.zip' $exists = Test-Path -LiteralPath $packagePath -PathType Leaf $hashValid = $false $packageValid = $false $sizeMB = $null $archiveDefinitionValid = ( $manifest.Archive -and [string]$manifest.Archive.FileName -eq 'Package.zip' -and [string]$manifest.Archive.Sha256 -match '^[A-Fa-f0-9]{64}$' ) if ($exists) { $sizeMB = [math]::Round((Get-Item -LiteralPath $packagePath).Length / 1MB, 1) if ($archiveDefinitionValid) { $actualHash = (Get-FileHash -LiteralPath $packagePath -Algorithm SHA256).Hash $hashValid = $actualHash.Equals([string]$manifest.Archive.Sha256, [System.StringComparison]::OrdinalIgnoreCase) } $packageValid = (Test-OSDAppPackage -PackagePath $packagePath).Valid } $architectureValid = ( ([string]$manifest.Architecture).ToLowerInvariant() -in @('x64','arm64','any') -and ([string]$manifest.Architecture).ToLowerInvariant() -eq ([string]$packageRef.Architecture).ToLowerInvariant() ) $idValid = [string]$manifest.Id -eq [string]$application.Id $successCodes = @($manifest.SuccessCodes) $successCodesValid = ( $successCodes.Count -gt 0 -and @($successCodes | Where-Object { ($_ -as [int]) -eq $null }).Count -eq 0 ) [pscustomobject]@{ PSTypeName = 'OSDApps.RepositoryValidation' Id = $manifest.Id Version = $manifest.Version Architecture = $manifest.Architecture ManifestExists = $true PackageExists = $exists HashValid = $hashValid PackageValid = $packageValid ArchitectureValid = $architectureValid IdValid = $idValid SuccessCodesValid = $successCodesValid ArchiveDefinitionValid = $archiveDefinitionValid DuplicateReference = $duplicateReference Orphaned = $false SizeMB = $sizeMB RepositoryFreeSpaceGB = $repositoryFreeSpaceGB Valid = ( $exists -and $hashValid -and $packageValid -and $architectureValid -and $idValid -and $successCodesValid -and $archiveDefinitionValid -and -not $duplicateReference ) } } } $appsRoot = Join-Path $resolvedRepository 'Apps' if (Test-Path -LiteralPath $appsRoot -PathType Container) { foreach ($manifestFile in @(Get-ChildItem -LiteralPath $appsRoot -Filter 'manifest.json' -File -Recurse -ErrorAction SilentlyContinue)) { $fullPath = [IO.Path]::GetFullPath($manifestFile.FullName) if (-not $referencedManifestPaths.Contains($fullPath)) { $orphanManifest = $null try { $orphanManifest = Get-Content -LiteralPath $manifestFile.FullName -Raw -Encoding UTF8 | ConvertFrom-Json } catch { } $orphanPackage = Join-Path $manifestFile.DirectoryName 'Package.zip' [pscustomobject]@{ PSTypeName = 'OSDApps.RepositoryValidation' Id = if ($orphanManifest) { $orphanManifest.Id } else { $null } Version = if ($orphanManifest) { $orphanManifest.Version } else { $null } Architecture = if ($orphanManifest) { $orphanManifest.Architecture } else { $null } ManifestExists = $true PackageExists = Test-Path -LiteralPath $orphanPackage -PathType Leaf HashValid = $false PackageValid = $false ArchitectureValid = $false IdValid = $false SuccessCodesValid = $false ArchiveDefinitionValid = $false DuplicateReference = $false Orphaned = $true SizeMB = if (Test-Path -LiteralPath $orphanPackage -PathType Leaf) { [math]::Round((Get-Item -LiteralPath $orphanPackage).Length / 1MB, 1) } else { $null } RepositoryFreeSpaceGB = $repositoryFreeSpaceGB Valid = $false } } } } } |