Moin,
da das Thema so ein bisschen durch mich aufgeploppt ist, wollte ich ein paar Powershell Funktionen, die ich mir beim Migrieren von AutoIt zu PS geschrieben habe teilen.
Vielleicht hilft dies anderen, egal ob fürs Migrieren oder weil er/sie einfach das für PS sucht.
Achtung: Es sind auch ein paar sehr spezielle API Funktionen für Soti Mobicontrol dabei.
PowerShell
$Logfile = ".\Output_$((Get-Date).ToString("yyyy-MM-dd_HH-mm-ss")).log"
Function LogWrite{
Param (
[string]$logstring,
[string]$Type = 'INFO',
[bool]$Debug = $false
)
If ($Debug) {
Write-Host "$Type`: $logstring"
}
Add-content $Logfile -value "$((Get-Date).ToString("yyyy-MM-dd_HH-mm-ss")) - $Type - $logstring"
}
Function SendMail {
Param (
[string]$Path,
[string]$To,
[string]$CC,
[string]$Subject,
[string]$Body,
[string]$Attachments = '',
[bool]$Debug = $false
)
Set-Variable olMailItem -option Constant -value 0 -ErrorAction Ignore
Set-Variable olFormatHTML -option Constant -value 2 -ErrorAction Ignore
If ($Debug) { LogWrite "$Path - Sending mail to: $To, CC: $CC, Subject: $Subject, Body: $Body, Attachments: $Attachments" 'DEBUG' $Debug }
$outlook = New-Object -ComObject Outlook.Application
$mail = $outlook.CreateItem($olMailItem)
$mail.To = $To
$mail.CC = $CC
$mail.Subject = $Subject
$mail.BodyFormat = $olFormatHTML
$mail.HTMLBody = $Body
$mail.Attachments.Add($Attachments)
$Result = $mail.Send()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($mail) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null
return $Result
}
Function EncodeStatusCode { #returns true/false based on the response code
param (
[string]$ResponseValue,
[bool]$Debug = $false
)
Switch ($ResponseValue) {
'200' {
if ($Debug) { LogWrite "EncodeStatusCode - Data retrieved successfully" 'INFO' $false }
Return $true
}
'204' {
if ($Debug) { LogWrite "EncodeStatusCode - Data permitted successfully" 'INFO' $false }
Return $true
}
'400' {
if ($Debug) { LogWrite "EncodeStatusCode - Contract validation error" 'ERROR' $false }
Return $false
}
'401' {
if ($Debug) { LogWrite "EncodeStatusCode - Authentication error" 'ERROR' $false }
Return $false
}
'403' {
if ($Debug) { LogWrite "EncodeStatusCode - No user permission to read the data" 'ERROR' $false }
Return $false
}
'422' {
if ($Debug) { LogWrite "EncodeStatusCode - Logic error" 'ERROR' $false }
Return $false
}
'500' {
if ($Debug) { LogWrite "EncodeStatusCode - Internal Server Error" 'ERROR' $false }
Return $false
}
Default {
if ($Debug) { LogWrite "EncodeStatusCode - Unknown error: $ResponseValue" 'ERROR' $false }
Return $false
}
}
}
# MobiControl API
# https://servername/MobiControl/api/token
function SendTokenRequest { #returns an access token
param (
[string]$Target,
[string]$Method,
[string]$Request,
$OptionalData = $null,
[bool]$Debug = $false
)
$Url = "https://$Target$Request"
$Authorization = ConvertIntoBase64("$ID`:$Secret")
$headers = @{
Authorization = "Basic $Authorization"
}
If ($Debug -eq $true) {
LogWrite "$Target - URL: $Url" 'DEBUG' $Debug
LogWrite "$Target - Headers: $($headers | Out-String)" 'DEBUG' $Debug
LogWrite "$Target - Data: $OptionalData" 'DEBUG' $Debug
}
$response = Invoke-WebRequest -Uri $Url -Method $Method -Headers $headers -ContentType 'application/x-www-form-urlencoded' -Body $OptionalData
$response = $response | Select-String -Pattern '"access_token":"([^"]+)"' -CaseSensitive -AllMatches
return $response.Matches.Groups[1].Value
}
# https://servername/MobiControl/api/...
function SendRequest {
param (
[string]$Target,
[string]$Method,
[string]$Request,
[string]$ContentType = 'application/json',
[string]$ReturnType = 'Content',
$OptionalData = $null,
[bool]$Debug = $false
)
$Url = "https://$Target$Request"
$headers = @{
Accept = $ContentType
Authorization = "Bearer $accessToken"
}
If ($Debug -eq $true) {
LogWrite "$Target - URL: $Url" 'DEBUG' $Debug
LogWrite "$Target - Headers: $($headers | Out-String)" 'DEBUG' $Debug
}
if ($null -eq $OptionalData) {
$response = Invoke-WebRequest -Uri $Url -Method $Method -Headers $headers -ContentType $ContentType
} else {
If ($Debug -eq $true) { LogWrite "$Target - Data: $OptionalData" 'DEBUG' $Debug}
$response = Invoke-WebRequest -Uri $Url -Method $Method -Headers $headers -ContentType $ContentType -Body $OptionalData
}
if ($Debug -eq $true) {
LogWrite "$Target - Response StatusCode: $($response.StatusCode)" 'DEBUG' $Debug
LogWrite "$Target - Response Content: $($response.$ReturnType)" 'DEBUG' $Debug
}
return $response.$ReturnType
}
# https://servername/MobiControl/api/customattributes
Function GetCustomAttributes{ #returns an array of all custom attributes with their names and IDs: Name | ID
param (
[bool]$Debug = $false
)
$Attributes = @(,0)
$Return = SendRequest $API 'GET' "/MobiControl/api/customattributes" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"Name": "([^"]+)"|"ReferenceId": "([^"]+)"' -CaseSensitive -AllMatches
For ($i = 0; $i -gt $Return.Matches.Count; $i++) {
If ($Debug) { LogWrite "$Path - Name: $($Return.Matches[$i].Groups[1].Value) - Value: $($Return.Matches[$i+1].Groups[2].Value)" 'DEBUG' $Debug }
$Attributes += ''
$Attributes[0] += 1
$Attributes[$Attributes[0]] = @("$($Return.Matches[$i].Groups[1].Value)", "$($Return.Matches[$i+1].Groups[2].Value)")
$i++
}
return $Attributes
}
# https://servername/MobiControl/api/customdata
Function GetCustomData{ #returns an array of all custom data with their names and IDs: Name | ID
param (
[bool]$Debug = $false
)
$Data = @(,0)
$Return = SendRequest $API 'GET' "/MobiControl/api/customdata" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"Name": "([^"]+)"|"ReferenceId": "([^"]+)"' -CaseSensitive -AllMatches
For ($i = 0; $i -lt $Return.Matches.Count; $i++) {
If ($Debug) { LogWrite "$Path - Name: $($Return.Matches[$i].Groups[1].Value) - ID: $($Return.Matches[$i+1].Groups[2].Value)" 'DEBUG' $Debug }
$Data += ''
$Data[0] += 1
$Data[$Data[0]] = @("$($Return.Matches[$i].Groups[1].Value)", "$($Return.Matches[$i+1].Groups[2].Value)")
$i++
}
return $Data
}
Function GetCustomAttributeValues{ #returns an array of all custom attributes with their names and Values: Name | Value
param (
[string]$Path,
[bool]$Debug = $false
)
$Values = @(,0)
$SotiPath = [URI]::EscapeUriString([URI]::EscapeUriString($Path))
$Return = SendRequest $API 'GET' "/MobiControl/api/devicegroups/$SotiPath/customAttributes" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Pattern = '"Name": "([^"]+)"|"Value": "([^"]+)"|"Value": ([^"]+),'
If ($Debug) { LogWrite "$Path - Pattern: $Pattern" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern $Pattern -CaseSensitive -AllMatches
If ($Debug) { LogWrite "$Path - Matches: $($Return.Matches)" 'DEBUG' $Debug }
For ($i = 0; $i -lt $Return.Matches.Count; $i++) {
If ($Debug) { LogWrite "$Path - Name: $($Return.Matches[$i].Groups[1].Value) - Value: $($Return.Matches[$i+1].Groups[2].Value)" 'DEBUG' $Debug }
$Values += ''
$Values[0] += 1
$Values[$Values[0]] = @("$($Return.Matches[$i].Groups[1].Value)", "$($Return.Matches[$i+1].Groups[2].Value)")
$i++
}
return $Values
}
function SetCustomAttribute { #sets the custom attribute for all devices in a group
param (
[string]$Path,
[string]$AttributeName,
[string]$Value,
[bool]$Debug = $false
)
$SotiPath = [URI]::EscapeUriString([URI]::EscapeUriString($Path))
$Content = "{`"Attributes`":[{`"AttributeName`":`"$AttributeName`",`"AttributeValue`":`"$Value`"}]}"
If ($Debug) {
LogWrite "$Path - Content: $Content" 'DEBUG' $true
LogWrite "$Path - /MobiControl/api/devicegroups/$SotiPath/customAttributes" 'DEBUG' $true
}
$Return = SendRequest $API 'PUT' "/MobiControl/api/devicegroups/$SotiPath/customAttributes" 'application/json' 'StatusCode' $Content $false
$EncodeStatusCode = EncodeStatusCode $Return $Debug
If ($Debug) { LogWrite "$Path - Return: $EncodeStatusCode" 'DEBUG' $true}
LogWrite "$Path - Set $AttributeName to $Value" 'INFO' $false
return $EncodeStatusCode
}
Function SetCustomAttribute_Path { #sets the custom attribute for all devices in a group
param (
[string]$Path,
$Values,
[string]$ValueName,
[string]$Value,
[bool]$Debug = $false
)
If ($null -eq $Value) {
LogWrite "$Path - No value provided for $ValueName`: $Value" 'ERROR' $false
return $false
}
For ($a = 1; $a -le $Values[0]; $a++) {
if ($Values[$a][0] -eq $ValueName -and $Values[$a][1] -ne $Value) {
LogWrite "$Path - Setting $ValueName to $Value" 'INFO' $false
$Values[$a][1] = $Value
if (SetCustomAttribute $Path $ValueName $Value $false) {
LogWrite "$Path - $ValueName set successfully" 'INFO' $false
return $true
} else {
LogWrite "$Path - Failed to set $ValueName" 'ERROR' $false
return $false
}
} elseif ($Values[$a][0] -eq $ValueName -and $Values[$a][1] -eq $Value) {
LogWrite "$Path - Name: $($Values[$a][0]) - Value: $($Values[$a][1]) (no change needed)" 'INFO' $false
return $true
}
}
LogWrite "$Path - $ValueName not found in custom attributes" 'ERROR' $false
return $false
}
function GetDevices {
param (
[string]$Path,
[string]$Filtertype = 'DeviceName', #DeviceName, IMEI_MEID_ESN, HardwareSerialNumber, LastAgentConnectTime, LastAgentDisconnectTime, DeviceId
[string]$Filter = '',
[string]$OrderType = '+', # + -> %2B
[string]$OrderField = $Filtertype,
[bool]$Debug = $false
)
if ($OrderType -eq "+") {
$OrderType = '%2B'
}
$Order = "$OrderType$OrderField"
$SotiPath = [System.Uri]::EscapeDataString($Path)
$Return = SendRequest $API 'GET' "/MobiControl/api/devices?path=$SotiPath&order=$Order" 'application/json' 'Content' $null $Debug
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | ConvertFrom-Json
$Devices = @(:Loop for($i = 0; $i -lt $Return.DeviceName.Count; $i += 1){
Switch ($Filtertype) {
'DeviceName' {
If ($Return.DeviceName[$i] -notlike "*$Filter*") {
continue Loop
}
}
'IMEI_MEID_ESN' {
If ($Return.IMEI_MEID_ESN[$i] -notlike "*$Filter*") {
continue Loop
}
}
'HardwareSerialNumber' {
If ($Return.HardwareSerialNumber[$i] -notlike "*$Filter*") {
continue Loop
}
}
'LastAgentConnectTime' {
If ($Return.LastAgentConnectTime[$i] -notlike "*$Filter*") {
continue Loop
}
}
'LastAgentDisconnectTime' {
If ($Return.LastAgentDisconnectTime[$i] -notlike "*$Filter*") {
continue Loop
}
}
}
[pscustomobject]@{
DeviceName = $Return.DeviceName[$i]
IMEI = $Return.IMEI_MEID_ESN[$i]
SerialNumber = $Return.HardwareSerialNumber[$i]
LastConnect = $Return.LastAgentConnectTime[$i]
LastDisconnect = $Return.LastAgentDisconnectTime[$i]
DeviceId = $Return.DeviceId[$i]
}
})
if ($Debug) { LogWrite "$Path - Devices: $Devices" 'DEBUG' $Debug }
return $Devices
}
Function GetOfflineDevices {
Param (
[string]$Path,
[int]$DurationValue = 30,
[string]$DurationType = 'DAYS', #DAYS, HOURS, MINUTES
[bool]$Debug = $false
)
$SotiPath = [URI]::EscapeUriString([URI]::EscapeUriString($Path))
if ($Debug) { LogWrite "$Path - Getting offline devices for more than $DurationValue $DurationType" 'DEBUG' $Debug }
$Return = SendRequest $API 'GET' "/MobiControl/api/devices/search?groupPath=$SotiPath&filter=LastAgentDisconnectTime%2520NOT%2520WITHIN%2520$DurationValue%2520$DurationType%2520AND%2520IsAgentOnline%2520%253D%2520FALSE&includeSubgroups=true&verifyAndSync=true&order=%2BDeviceName" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | ConvertFrom-Json
$timeformat = 'MM/dd/yyyy HH:mm:ss'
$Devices = @(for($i = 0; $i -lt $Return.DeviceName.Count; $i++){
$Now = Get-Date
$Offline = [datetime]::ParseExact(($Return.LastAgentDisconnectTime[$i]), $timeformat, [System.Globalization.CultureInfo]::InvariantCulture)
$DaysOffline = NEW-TIMESPAN -Start $Offline -End $Now
$DaysOffline = $DaysOffline.Days
if ($Return.DeviceName.Count -eq 1) {
if ($Debug) {
LogWrite "$Path\$($Return.DeviceName) - $($Return.LastAgentDisconnectTime)" 'DEBUG' $Debug
LogWrite "$Path\$($Return.DeviceName) - Online: $Now - Offline: $Offline - Days offline: $($DaysOffline)" 'DEBUG' $Debug
}
[pscustomobject]@{
DeviceName = $Return.DeviceName
Path = $Return.Path
Offline = $DaysOffline
IMEI = $Return.IMEI_MEID_ESN
SerialNumber = $Return.HardwareSerialNumber
}
} else {
if ($Debug) {
LogWrite "$Path\$($Return.DeviceName[$i]) - $($Return.LastAgentDisconnectTime[$i])" 'DEBUG' $Debug
LogWrite "$Path\$($Return.DeviceName[$i]) - Online: $Now - Offline: $Offline - Days offline: $($DaysOffline)" 'DEBUG' $Debug
}
[pscustomobject]@{
DeviceName = $Return.DeviceName[$i]
Path = $Return.Path[$i]
Offline = $DaysOffline
IMEI = $Return.IMEI_MEID_ESN[$i]
SerialNumber = $Return.HardwareSerialNumber[$i]
}
}
})
return $Devices
}
Function Getgroup {
Param (
[string]$Path,
[string]$GroupNumber,
[bool]$Debug
)
$Return = GetGroups $Path 'group' $false
If ($Debug) { LogWrite "Return: $Return" 'DEBUG' $Debug }
If ($Return -contains $GroupNumber) {
Return $true
}
Return $false
}
Function GetGroups{ #returns an array of all groups in a given path and mode: Name
param (
[string]$Path,
[string]$Mode,
[bool]$Debug = $false
)
if ($Mode -eq 'A') { # replaced our expectations, so need to be aligned for own usage
$Length = 10
} elseif ($Mode -eq 'B') {
$Length = 11
} elseif ($Mode -eq 'C') {
$Length = 12
} elseif ($Mode -eq 'D') {
$Length = 99
}
$SotiPath = [URI]::EscapeUriString([URI]::EscapeUriString($Path))
$Groups = @(,0)
$Return = SendRequest $API 'GET' "/MobiControl/api/devicegroups?parentPath=$SotiPath" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"Name": "([^"]+)"' -CaseSensitive -AllMatches
For ($i = 0; $i -lt $Return.Matches.Count; $i++) {
If ($Return.Matches[$i].Groups[1].Value.Length -le $Length) {
$Groups += "$($Return.Matches[$i].Groups[1].Value)"
$Groups[0] += 1
if ($Debug) { LogWrite "$Path - Added: $($Return.Matches[$i].Groups[1].Value)" 'DEBUG' $Debug }
}
}
return $Groups
}
Function AddGroup {
Param (
[string]$Path,
[string]$GroupNumber,
[bool]$Debug
)
$SotiPath = "$Path\$GroupNumber" -replace '\\','\\'
If ($Debug) { LogWrite "SotiPath: $SotiPath" 'DEBUG' $Debug }
$Data = '{"Name":"' + $GroupNumber + '","Path":"' + $SotiPath + '","Icon":"None","Kind": "Regular"}'
If ($Debug) { LogWrite "Data: $Data" 'DEBUG' $Debug }
$Return = SendRequest $API 'POST' '/MobiControl/api/devicegroups' 'application/json' 'Content' $Data $False
If ($Debug) { LogWrite "Return: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"ReferenceId": "([^"]+)"' -CaseSensitive -AllMatches
return $Return.Matches.Groups[1].Value
}
Function GetDeviceGroupID {
Param (
[string]$Path,
[bool]$Debug = $false
)
$SotiPath = [URI]::EscapeUriString([URI]::EscapeUriString($Path))
$Return = SendRequest $API 'GET' "/MobiControl/api/devicegroups/$SotiPath" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Path - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"ReferenceId": "([^"]+)"' -CaseSensitive -AllMatches
$ID = $Return.Matches.Groups[1].Value
return $ID
}
Function GetRelocationID {
Param (
[string]$Name,
[bool]$Debug = $false
)
$Return = SendRequest $API 'GET' "/MobiControl/api/deviceRelocationPolicies?searchString=$Name&statuses=Assigned" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Name - Return: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"ReferenceId": "([^"]+)"' -CaseSensitive -AllMatches
$ID = $Return.Matches.Groups[1].Value
return $ID
}
Function GetRelocationData {
Param (
[string]$RelocationRuleID,
[string]$GroupID,
[string]$Group,
[bool]$Debug = $false
)
$Values = @(,0)
$Return = SendRequest $API 'GET' "/MobiControl/api/deviceRelocationPolicies/$RelocationRuleID" 'application/json' 'Content' $null $false
If ($Debug) { LogWrite "$Group - GetRelocationData Response: $Return" 'DEBUG' $Debug }
$Return = $Return | Select-String -Pattern '"DeviceGroupReferenceId": "([^"]+)"|"DeviceGroupPath": "([^"]+)"' -CaseSensitive -AllMatches
For ($i = 0; $i -le $Return.Matches.Count-1; $i++) {
If ($Debug) { LogWrite "$Group - DeviceGroupReferenceId: $($Return.Matches[$i].Groups[1].Value) - DeviceGroupPath: $($Return.Matches[$i+1].Groups[2].Value)" 'DEBUG' $Debug }
$Values += ''
$Values[0] += 1
$Values[$Values[0]] = @("$($Return.Matches[$i].Groups[1].Value)", "$($Return.Matches[$i+1].Groups[2].Value)")
if ($Debug) { LogWrite "$Group - Added Data Values ($i/$($i+1)/$($Return.Matches.Count)): $($Return.Matches[$i].Groups[1].Value) | $($Return.Matches[$i+1].Groups[2].Value)" }
$i++
}
$Values += ''
$Values[0] += 1
$Values[$Values[0]] = @("$GroupID", "$Group")
if ($Debug) {
LogWrite "$Group - Added Data Values ($i/$($i+1)/$($Return.Matches.Count)): $($Return.Matches[$i].Groups[1].Value) | $($Return.Matches[$i+1].Groups[2].Value)"
LogWrite "$Group - Relocation Data Values: $Values" 'DEBUG' $Debug
}
return $Values
}
$login = Get-Credential
$accessToken = SendTokenRequest $API 'POST' '/MobiControl/api/token' "grant_type=password&username=$($login.UserName)&password=$($login.GetNetworkCredential().Password)" $false
Alles anzeigen