Thursday, May 2, 2024
HomePowershellSimplifying PowerShell Object Validation & Remodeling: A JSON-Schema Refactoring Journey

Simplifying PowerShell Object Validation & Remodeling: A JSON-Schema Refactoring Journey


In a current scripting endeavor, I developed a PowerShell script with an ArgumentTransformationAttribute. The script’s goal was to transform PSCustomObjects or Hashtables right into a JSON format tailor-made for seamless integration with a BatchRequest destined for the Microsoft Graph API.

class JSONTransform : System.Administration.Automation.ArgumentTransformationAttribute{
    [object] Remodel([System.Management.Automation.EngineIntrinsics]$EngineIntrinsics,[object]$InputData){
        $MandatoryKeys = @("url","id","methodology")
        $ValidKeys = $MandatoryKeys+@(,"headers","physique")
        $ValidMethods = @("Get","Publish","Put","Patch","Delete")

        Swap ($InputData){
            {$_ -is [PSObject]}{
                $_.psobject.properties.title.ForEach({
                    if(-Not $ValidKeys.Comprises($_)){
                        throw "Invalid psobject keys"
                    }
                })       
                if((Examine-Object -ReferenceObject $MandatoryKeys -DifferenceObject @($_.PSObject.Properties.Title) -IncludeEqual -ExcludeDifferent).Depend -ne $MandatoryKeys.Depend){
                    throw "Lacking obligatory keys"
                }         
                if(-not $ValidMethods -Comprises $_.Methodology){
                    throw "Methodology have to be: Get, Delete, Patch, Put, Publish"
                }
                if($_.URL -notmatch '^/[a-zA-Z0-9/$&=?,]+$'){
                    throw "the url will not be in a correct sample"
                }
            }
            {$_ -is [hashtable]}{
                $_.Keys.ForEach({
                    if(-Not $ValidKeys -Comprises($_)){
                        throw "Invalid Hashtable keys"
                    }
                })
                if((Examine-Object -ReferenceObject $MandatoryKeys -DifferenceObject @($_.Keys) -IncludeEqual -ExcludeDifferent).Depend -ne $MandatoryKeys.Depend){
                    throw "Lacking obligatory keys"
                }
                if(-not $ValidMethods -Comprises $_["Method"]){
                    throw "Methodology have to be: Get, Delete, Patch, Put, Publish"
                }
                if($_['URL'] -notmatch '^/[a-zA-Z0-9/$&=?,]+$'){
                    throw "the url will not be in a correct sample"
                }
            }
            Default{
                throw "Mistaken Enter kind"
            }
            
        }
        $ReturnObject = @{
            requests = $InputData
        }
        return $ReturnObject | ConvertTo-Json -Depth 4
    }
}

Amidst this coding journey, redundancy surfaced throughout the class. Looking for a streamlined method, I explored JSON-Schema validation, an environment friendly resolution. This methodology allowed me to encapsulate all vital specs inside a single schema, eliminating the necessity to differentiate between object sorts.

{
  "properties": {
    "requests": {
      "objects": {
        "properties": {
          "physique": {
            "kind": "object"
          },
          "url": {
            "sample": "^/[a-zA-Z0-9/$&=?,]+$",
            "kind": "string"
          },
          "id": {
            "kind": "string"
          },
          "headers": {
            "kind": "object"
          },
          "methodology": {
            "enum": [
              "GET",
              "PUT",
              "PATCH",
              "POST",
              "DELETE"
            ],
            "kind": "string"
          }
        },
        "kind": "object",
        "propertyNames": {
          "enum": [
            "id",
            "method",
            "url",
            "headers",
            "body"
          ]
        },
        "required": [
          "id",
          "method",
          "url"
        ]
      },
      "kind": "array"
    }
  },
  "kind": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "requests"
  ]
}

The category underwent a metamorphosis, shedding redundancy in favor of readability. The code now validates objects in opposition to the JSON schema, guaranteeing adherence to predefined guidelines.

class JSONTransform : System.Administration.Automation.ArgumentTransformationAttribute{
    [object] Remodel([System.Management.Automation.EngineIntrinsics]$EngineIntrinsics,[object]$InputData){
        $batchGraphRequestSchema = @{
            '$schema' = 'http://json-schema.org/draft-07/schema#'
            'kind' = 'object'
            'properties' = @{
                'requests' = @{
                    'kind' = 'array'
                    'objects' = @{
                        'kind' = 'object'
                        'properties' = @{
                            'id' = @{
                                'kind' = 'string'
                            }
                            'methodology' = @{
                                'kind' = 'string'
                                'enum' = @('GET', 'PUT', 'PATCH', 'POST', 'DELETE')
                            }
                            'url' = @{
                                'kind' = 'string'
                                'sample' = '^/[a-zA-Z0-9/$&=?,]+$'
                            }
                            'headers' = @{
                                'kind' = 'object'
                                
                            }
                            'physique' = @{
                                'kind' = 'object'
                                
                            }
                        }
                        'required' = @('id', 'methodology', 'url')
                        'propertyNames' = @{
                            'enum' = @('id', 'methodology', 'url', 'headers', 'physique')
                        }
                    }
                }
            }
            'required' = @('requests')
        }
        
        $ReturnObject = @{
            requests = $InputData
        } | ConvertTo-Json -Depth 6

        strive  Convertto-Json -Depth 6) -ErrorAction Cease
        
        catch {
            write-host $ReturnObject
            
            Throw "$($_.Exception.Message). JSON Schema didn't match"
        }
        return $ReturnObject
    }
}

This method not solely improves the transformation for Graph API batch requests but additionally holds promise for broader purposes in parameter validation eventualities. The JSON schema is a flexible software, able to implement guidelines and guarantee information integrity. Keep tuned for extra coding adventures!

In case you have any ideas or suggestions on this matter, be happy to share them with me on Twitter at Christian Ritter.

Finest regards,
Christian



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments