src/Get-ObjectSchemaAsArray.ps1

Function Get-ObjectSchemaAsArray
{
  <#
    .SYNOPSIS
    Gets the schema of the object as array with column-names and their type (strin, boolean, dynamic, etc.)
 
    .DESCRIPTION
    Used to validate the data structure - and give insight of any potential data manipulation
 
    .PARAMETER Data
    Object to modify
 
    .INPUTS
    None. You cannot pipe objects
 
    .OUTPUTS
    Updated object with CollectionTime
 
    .EXAMPLE
    $verbose = $true
 
    $TenantId = "xxxxx"
    $LogIngestAppId = "xxxxx"
    $LogIngestAppSecret = "xxxxx"
 
    $TableName = 'InvClientComputerOSInfoV2' # must not contain _CL
    $DcrName = "dcr-" + $AzDcrPrefixClient + "-" + $TableName + "_CL"
 
    $DceName = "dce-log-platform-management-client-demo1-p"
    $LogAnalyticsWorkspaceResourceId = "/subscriptions/xxxxxx/resourceGroups/rg-logworkspaces/providers/Microsoft.OperationalInsights/workspaces/log-platform-management-client-demo1-p"
    $AzDcrPrefixClient = "clt1"
 
    $AzDcrSetLogIngestApiAppPermissionsDcrLevel = $false
    $AzDcrLogIngestServicePrincipalObjectId = "xxxxxx"
 
    #-------------------------------------------------------------------------------------------
    # Collecting data (in)
    #-------------------------------------------------------------------------------------------
             
    Write-Output ""
    Write-Output "Collecting OS information ... Please Wait !"
 
    $DataVariable = Get-CimInstance -ClassName Win32_OperatingSystem
 
    #-------------------------------------------------------------------------------------------
    # Preparing data structure
    #-------------------------------------------------------------------------------------------
 
    # convert CIM array to PSCustomObject and remove CIM class information
    $DataVariable = Convert-CimArrayToObjectFixStructure -data $DataVariable -Verbose:$Verbose
     
    # add CollectionTime to existing array
    $DataVariable = Add-CollectionTimeToAllEntriesInArray -Data $DataVariable -Verbose:$Verbose
 
    # add Computer & UserLoggedOn info to existing array
    $DataVariable = Add-ColumnDataToAllEntriesInArray -Data $DataVariable -Column1Name Computer -Column1Data $Env:ComputerName -Column2Name UserLoggedOn -Column2Data $UserLoggedOn
 
    # Validating/fixing schema data structure of source data
    $DataVariable = ValidateFix-AzLogAnalyticsTableSchemaColumnNames -Data $DataVariable -Verbose:$Verbose
 
    # Aligning data structure with schema (requirement for DCR)
    $DataVariable = Build-DataArrayToAlignWithSchema -Data $DataVariable -Verbose:$Verbose
 
    $Schema = Get-ObjectSchemaAsArray -Data $DataVariable
    $Schema
 
    #-------------------------------------------------------------------------------------------
    # Output
    #-------------------------------------------------------------------------------------------
    name type
    ---- ----
    BootDevice string
    BuildNumber string
    BuildType string
    Caption string
    CodeSet string
    CollectionTime datetime
    Computer string
    CountryCode string
    CreationClassName string
    CSCreationClassName string
    CSDVersion dynamic
    CSName string
    CurrentTimeZone int
    DataExecutionPrevention_32BitApplications boolean
    DataExecutionPrevention_Available boolean
    DataExecutionPrevention_Drivers boolean
    DataExecutionPrevention_SupportPolicy int
    Debug boolean
    Description string
    Distributed boolean
    EncryptionLevel int
    ForegroundApplicationBoost int
    FreePhysicalMemory int
    FreeSpaceInPagingFiles int
    FreeVirtualMemory int
    InstallDate datetime
    LargeSystemCache dynamic
    LastBootUpTime datetime
    LocalDateTime datetime
    Locale string
    Manufacturer string
    MaxNumberOfProcesses long
    MaxProcessMemorySize long
    MUILanguages dynamic
    Name string
    NumberOfLicensedUsers int
    NumberOfProcesses int
    NumberOfUsers int
    OperatingSystemSKU int
    Organization dynamic
    OSArchitecture string
    OSLanguage int
    OSProductSuite int
    OSType int
    OtherTypeDescription dynamic
    PAEEnabled dynamic
    PlusProductID dynamic
    PlusVersionNumber dynamic
    PortableOperatingSystem boolean
    Primary boolean
    ProductType int
    PSComputerName dynamic
    RegisteredUser string
    SerialNumber string
    ServicePackMajorVersion int
    ServicePackMinorVersion int
    SizeStoredInPagingFiles int
    Status string
    SuiteMask int
    SystemDevice string
    SystemDirectory string
    SystemDrive string
    TotalSwapSpaceSize dynamic
    TotalVirtualMemorySize int
    TotalVisibleMemorySize int
    UserLoggedOn string
    Version string
    WindowsDirectory string
 
  #>


    [CmdletBinding()]
    param(
            [Parameter(mandatory)]
                [Array]$Data,
            [Parameter()]
                [ValidateSet("Table", "DCR")]
                [string[]]$ReturnType
         )


        $SchemaArrayLogAnalyticsTableFormat = @()
        $SchemaArrayDcrFormat = @()
        $SchemaArrayLogAnalyticsTableFormatHash = @()
        $SchemaArrayDcrFormatHash = @()

        # Requirement - Add TimeGenerated to array
        $SchemaArrayLogAnalyticsTableFormatHash += @{
                                                     name        = "TimeGenerated"
                                                     type        = "datetime"
                                                     description = ""
                                                    }

        $SchemaArrayLogAnalyticsTableFormat += [PSCustomObject]@{
                                                     name        = "TimeGenerated"
                                                     type        = "datetime"
                                                     description = ""
                                               }

        # Loop source object and build hash for table schema
        ForEach ($Entry in $Data)
            {
                $ObjColumns = $Entry | ConvertTo-Json -Depth 100 | ConvertFrom-Json | Get-Member -MemberType NoteProperty
                ForEach ($Column in $ObjColumns)
                    {
                        $ObjDefinitionStr = $Column.Definition
                                If ($ObjDefinitionStr -like "int*")                                            { $ObjType = "int" }
                            ElseIf ($ObjDefinitionStr -like "real*")                                           { $ObjType = "int" }
                            ElseIf ($ObjDefinitionStr -like "long*")                                           { $ObjType = "long" }
                            ElseIf ($ObjDefinitionStr -like "guid*")                                           { $ObjType = "dynamic" }
                            ElseIf ($ObjDefinitionStr -like "string*")                                         { $ObjType = "string" }
                            ElseIf ($ObjDefinitionStr -like "datetime*")                                       { $ObjType = "datetime" }
                            ElseIf ($ObjDefinitionStr -like "bool*")                                           { $ObjType = "boolean" }
                            ElseIf ($ObjDefinitionStr -like "object*")                                         { $ObjType = "dynamic" }
                            ElseIf ($ObjDefinitionStr -like "System.Management.Automation.PSCustomObject*")    { $ObjType = "dynamic" }

                        # build for array check
                        $SchemaLogAnalyticsTableFormatObjHash = @{
                                                                   name        = $Column.Name
                                                                   type        = $ObjType
                                                                   description = ""
                                                                 }

                        $SchemaLogAnalyticsTableFormatObj     = [PSCustomObject]@{
                                                                   name        = $Column.Name
                                                                   type        = $ObjType
                                                                   description = ""
                                                                }
                        $SchemaDcrFormatObjHash = @{
                                                      name        = $Column.Name
                                                      type        = $ObjType
                                                   }

                        $SchemaDcrFormatObj     = [PSCustomObject]@{
                                                      name        = $Column.Name
                                                      type        = $ObjType
                                                  }


                        If ($Column.Name -notin $SchemaArrayLogAnalyticsTableFormat.name)
                            {
                                $SchemaArrayLogAnalyticsTableFormat       += $SchemaLogAnalyticsTableFormatObj
                                $SchemaArrayDcrFormat                     += $SchemaDcrFormatObj

                                $SchemaArrayLogAnalyticsTableFormatHash   += $SchemaLogAnalyticsTableFormatObjHash
                                $SchemaArrayDcrFormatHash                 += $SchemaDcrFormatObjHash
                            }
                    }
            }

            If ($ReturnType -eq "Table")
            {
                # Return schema format for LogAnalytics table
                Return $SchemaArrayLogAnalyticsTableFormat
            }
        ElseIf ($ReturnType -eq "DCR")
            {
                # Return schema format for DCR
                Return $SchemaArrayDcrFormat
            }
        Else
            {
                # Return schema format for DCR
                Return $SchemaArrayDcrFormat
            }
}