powershellwrapper icon indicating copy to clipboard operation
powershellwrapper copied to clipboard

Special Characters

Open BenWallmeyer opened this issue 5 years ago • 8 comments

This Script is used for Autodocumentation Hyper-V. The Problem is in lot of Scripts we use. German Umlauts will not Upload to traits. It show only �

########################## IT-Glue ############################
param(
[string]$OrgID = ""
)
$APIKEy =  ""
$APIEndpoint = "https://api.eu.itglue.com"
$FlexAssetName = "Hyper-v AutoDoc v2"
$Description = "A network one-page document that displays the current Hyper-V Settings and virtual machines"
#some layout options, change if you want colours to be different or do not like the whitespace.
$TableHeader = "<table class=`"table table-bordered table-hover`" style=`"width:80%`">"
$Whitespace = "<br/>"
$TableStyling = "<th>", "<th style=`"background-color:#4CAF50`">"
########################## IT-Glue ############################
#Grabbing ITGlue Module and installing.
If (Get-Module -ListAvailable -Name "ITGlueAPI") { 
    Import-module ITGlueAPI 
}
Else { 
    Install-PackageProvider -Name -NuGet -MinimumVersion 2.8.5.201 -Force
    Install-Module ITGlueAPI -Force
    Import-Module ITGlueAPI
}
#Settings IT-Glue logon information
Add-ITGlueBaseURI -base_uri $APIEndpoint
Add-ITGlueAPIKey $APIKEy
write-host "Checking if Flexible Asset exists in IT-Glue." -foregroundColor green
$FilterID = (Get-ITGlueFlexibleAssetTypes -filter_name $FlexAssetName).data
if (!$FilterID) { 
    write-host "Does not exist, creating new." -foregroundColor green
    $NewFlexAssetData = 
    @{
        type          = 'flexible-asset-types'
        attributes    = @{
            name        = $FlexAssetName
            icon        = 'sitemap'
            description = $description
        }
        relationships = @{
            "flexible-asset-fields" = @{
                data = @(
                    @{
                        type       = "flexible_asset_fields"
                        attributes = @{
                            order           = 1
                            name            = "Host name"
                            kind            = "Text"
                            required        = $true
                            "show-in-list"  = $true
                            "use-for-title" = $true
                        }
                    },
                    @{
                        type       = "flexible_asset_fields"
                        attributes = @{
                            order          = 2
                            name           = "Virtual Machines"
                            kind           = "Textbox"
                            required       = $false
                            "show-in-list" = $false
                        }
                    },
                    @{
                        type       = "flexible_asset_fields"
                        attributes = @{
                            order          = 3
                            name           = "Network Settings"
                            kind           = "Textbox"
                            required       = $false
                            "show-in-list" = $false
                        }
                    },
                    @{
                        type       = "flexible_asset_fields"
                        attributes = @{
                            order          = 4
                            name           = "Replication Settings"
                            kind           = "Textbox"
                            required       = $false
                            "show-in-list" = $false
                        }
                    },
                    @{
                        type       = "flexible_asset_fields"
                        attributes = @{
                            order          = 5
                            name           = "Host Settings"
                            kind           = "Textbox"
                            required       = $false
                            "show-in-list" = $tru
                        }
                    }
                )
            }
        }
    }
    New-ITGlueFlexibleAssetTypes -Data $NewFlexAssetData
    $FilterID = (Get-ITGlueFlexibleAssetTypes -filter_name $FlexAssetName).data
}
 
write-host "Start documentation process." -foregroundColor green
 
$VirtualMachines = get-vm | select-object VMName, Generation, Path, Automatic*, @{n = "Minimum(gb)"; e = { $_.memoryminimum / 1gb } }, @{n = "Maximum(gb)"; e = { $_.memorymaximum / 1gb } }, @{n = "Startup(gb)"; e = { $_.memorystartup / 1gb } }, @{n = "Currently Assigned(gb)"; e = { $_.memoryassigned / 1gb } }, ProcessorCount | ConvertTo-Html -Fragment | Out-String
$VirtualMachines = $TableHeader + ($VirtualMachines -replace $TableStyling) + $Whitespace
$NetworkSwitches = Get-VMSwitch | select-object name, switchtype, NetAdapterInterfaceDescription, AllowManagementOS | convertto-html -Fragment -PreContent "<h3>Network Switches</h3>" | Out-String
$VMNetworkSettings = Get-VMNetworkAdapter * | Select-Object Name, IsManagementOs, VMName, SwitchName, MacAddress, @{Name = 'IP'; Expression = { $_.IPaddresses -join "," } } | ConvertTo-Html -Fragment -PreContent "<br><h3>VM Network Settings</h3>" | Out-String
$NetworkSettings = $TableHeader + ($NetworkSwitches -replace $TableStyling) + ($VMNetworkSettings -replace $TableStyling) + $Whitespace
$ReplicationSettings = get-vmreplication | Select-Object VMName, State, Mode, FrequencySec, PrimaryServer, ReplicaServer, ReplicaPort, AuthType | convertto-html -Fragment | Out-String
$ReplicationSettings = $TableHeader + ($ReplicationSettings -replace $TableStyling) + $Whitespace
$HostSettings = get-vmhost | Select-Object  Computername, LogicalProcessorCount, iovSupport, EnableEnhancedSessionMode,MacAddressMinimum, *max*, NumaspanningEnabled, VirtualHardDiskPath, VirtualMachinePath, UseAnyNetworkForMigration, VirtualMachineMigrationEnabled | convertto-html -Fragment -as List | Out-String
 
$FlexAssetBody =
@{
    type       = 'flexible-assets'
    attributes = @{
        traits = @{
            'host-name'            = $env:COMPUTERNAME
            'virtual-machines'     = $VirtualMachines
            'network-settings'     = $NetworkSettings
            'replication-settings' = $ReplicationSettings
            'host-settings'        = $HostSettings
        }
    }
}
write-host $env:COMPUTERNAME 
write-host "Documenting to IT-Glue"  -ForegroundColor Green
$ExistingFlexAsset = (Get-ITGlueFlexibleAssets -filter_flexible_asset_type_id $($filterID.ID) -filter_organization_id $OrgID).data | Where-Object { $_.attributes.traits.'host-name' -eq $ENV:computername }
#If the Asset does not exist, we edit the body to be in the form of a new asset, if not, we just upload.
if (!$ExistingFlexAsset) {
    $FlexAssetBody.attributes.add('organization-id', $OrgID)
    $FlexAssetBody.attributes.add('flexible-asset-type-id', $($filterID.ID))
    write-host "  Creating Hyper-v into IT-Glue organisation $OrgID" -ForegroundColor Green

    New-ITGlueFlexibleAssets -data $FlexAssetBody
}
else {
    write-host "  Editing Hyper-v into IT-Glue organisation $OrgID"  -ForegroundColor Green
    $ExistingFlexAsset = $ExistingFlexAsset[-1]
    Set-ITGlueFlexibleAssets -id $ExistingFlexAsset.id -data $FlexAssetBody
}

In This case the error only comes here type = 'flexible-assets' attributes = @{ traits = @{ 'host-name' = $env:COMPUTERNAME 'virtual-machines' = $VirtualMachines 'network-settings' = $NetworkSettings 'replication-settings' = $ReplicationSettings 'host-settings' = $HostSettings } } }

In HTML Table it will work.

Is there any Solution to get this and the Other Scripts working.

BenWallmeyer avatar May 18 '20 12:05 BenWallmeyer

See issue #12.

Easiest fix for this is to edit your module files and add the $body = [System.Text.Encoding]::UTF8.GetBytes($body) before Invoke-RestMethod.

In your case, you would have to edit both Set-ITGlueFlexibleAssets and New-ITGlueFlexibleAssets here: \ITGlueAPI\Resources\FlexibleAssets.ps1. This would have to be done with any function where you want to support special characters.

function New-ITGlueFlexibleAssets {
    Param (
        [Parameter(Mandatory = $true)]
        $data
    )

    $resource_uri = '/flexible_assets/'

    $body = @{}

    $body += @{'data'= $data}

    $body = ConvertTo-Json -InputObject $body -Depth $ITGlue_JSON_Conversion_Depth

    # Put it here
    $body = [System.Text.Encoding]::UTF8.GetBytes($body)

    try {
        $ITGlue_Headers.Add('x-api-key', (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'N/A', $ITGlue_API_Key).GetNetworkCredential().Password)
        $rest_output = Invoke-RestMethod -method 'POST' -uri ($ITGlue_Base_URI + $resource_uri) -headers $ITGlue_Headers `
            -body $body -ErrorAction Stop -ErrorVariable $web_error
    } catch {
        Write-Error $_
    } finally {
        [void] ($ITGlue_Headers.Remove('x-api-key')) # Quietly clean up scope so the API key doesn't persist
    }

    $data = @{}
    $data = $rest_output
    return $data
}

and

function Set-ITGlueFlexibleAssets {
    [CmdletBinding(DefaultParameterSetName = 'update')]
    Param (
        [Parameter(ParameterSetName = 'update')]
        [Nullable[Int64]]$id = $null,

        [Parameter(ParameterSetName = 'update')]
        [Parameter(ParameterSetName = 'bulk_update')]
        [Parameter(Mandatory = $true)]
        $data
    )

    $resource_uri = ('/flexible_assets/{0}' -f $id)

    $body = @{}

    $body += @{'data' = $data}

    $body = ConvertTo-Json -InputObject $body -Depth $ITGlue_JSON_Conversion_Depth

    # And here
    $body = [System.Text.Encoding]::UTF8.GetBytes($body)

    try {
        $ITGlue_Headers.Add('x-api-key', (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'N/A', $ITGlue_API_Key).GetNetworkCredential().Password)
        $rest_output = Invoke-RestMethod -method 'PATCH' -uri ($ITGlue_Base_URI + $resource_uri) -headers $ITGlue_Headers `
            -body $body -ErrorAction Stop -ErrorVariable $web_error
    } catch {
        Write-Error $_
    } finally {
        [void] ($ITGlue_Headers.Remove('x-api-key')) # Quietly clean up scope so the API key doesn't persist
    }

    $data = @{}
    $data = $rest_output
    return $data
}

ecspresso avatar May 18 '20 14:05 ecspresso

Thanks this works. Will it be pushed into main?

BenWallmeyer avatar May 18 '20 20:05 BenWallmeyer

A decision on that has not been made as far as I know.

ecspresso avatar May 25 '20 08:05 ecspresso

Ok so i have to wait cause we can't use the Wrapper without chnaging module files

BenWallmeyer avatar May 25 '20 11:05 BenWallmeyer

You could do a find and replace (or manually update) all the files.

ecspresso avatar May 26 '20 09:05 ecspresso

Yes i have changed and it work. But this we must do for every Customer. And there are a lot of German Users which have the same Problem. So i think the better way is to implement this in the Module directly. Like a Param or a function to change the Encoding

BenWallmeyer avatar May 26 '20 09:05 BenWallmeyer

hey ive copied the function into my main code and rename it to "set-itglueflexibaleassets2" so it will work for every of your costumers

Yaspo90 avatar Nov 24 '20 10:11 Yaspo90

@BenWallmeyer A new solution is in the works, see the latest comments in #12.

ecspresso avatar Aug 11 '21 08:08 ecspresso

Duplicate of #12.

davidhaymond avatar Dec 05 '22 19:12 davidhaymond