0

J'ai écrit un script Automation dans PowerShell qui me donne chaque matin un rapport sur nos abonnements azure (Vm, travaux d'automatisation, alertes, ...). Maintenant, j'ajoute une nouvelle fonction qui fonctionne bien à partir de mon ordinateur mais qui échoue lorsqu'elle est exécutée depuis Automation et je ne trouve pas comment la faire fonctionner.Script Azure Automation pour demander OMS

Fonctionne bien de mon ordinateur (VS code/PS 5.1/PS 4,0)

$omsRGname = "xxx" 
$omsWorkspaceName = "xxx" 
$omsQueryThreat = 'Type=ProtectionStatus ThreatStatusRank!=150 ThreatStatusRank!=470 | select Computer,Threat,ThreatStatus' 
$ArrayThreat = New-Object System.Collections.ArrayList 

function OmsRequest { 
    Param(
     [parameter(Position = 0, Mandatory = $true)] 
     $omsRG, 
     [parameter(Position = 1, Mandatory = $true)] 
     $omsWorkspace, 
     [parameter(Position = 2, Mandatory = $true)] 
     $omsQuery 
    ) 
    Process { 
     Import-Module AzureRm.OperationalInsights 
     $error.clear() 
     $Result.clear 
     $script:Result = Get-AzureRmOperationalInsightsSearchResults -ResourceGroupName $omsRG -WorkspaceName $omsWorkspace -Query $omsQuery 
     $reqIdParts = $Result.Id.Split("/") 
     $reqId = $reqIdParts[$reqIdParts.Count - 1] 
     $wait = Get-Date 
     while ($Result.Metadata.Status -eq "Pending" -and $error.Count -eq 0) { 
      $Result = Get-AzureRmOperationalInsightsSearchResults -WorkspaceName $omsWorkspace -ResourceGroupName $omsRG -Id $reqId 
      #debug 
      $elapsedTime = $(get-date) - $wait 
      Write-Output "Elapsed: $elapsedTime -- Status: $($Result.Metadata.Status)" 
      Write-Output "Count: $($Result.Count)" 
     } 
    } 
} 

OmsRequest $omsRGname $omsWorkspaceName $omsQueryThreat 
#debug 
Write-Output "VALUEOUT:" $Result.Value 
# 
$OMSComputers = $Result.Value | ConvertFrom-Json 
if ($OMSComputers) { 
    foreach ($ThreatDetails in $OMSComputers) { 
     <#write "$(get-date($ThreatDetails.__metadata.TimeGenerated) -format G) - $($ThreatDetails.Computer) - $($ThreatDetails.Threat) - $($ThreatDetails.ThreatStatus)"#> 
     $ThDetails = [PSCustomObject] @{ 
      Date   = (get-date($ThreatDetails.__metadata.TimeGenerated) -format G); 
      Computer  = $ThreatDetails.Computer; 
      Threat  = $ThreatDetails.Threat; 
      ThreatStatus = $ThreatDetails.ThreatStatus; 
     } 
     $ArrayThreat.Add($ThDetails) |Out-Null 
    } 
} 
else {Write-Output "OK"} 

$ArrayThreat 

de mon ordinateur local

Elapsed: 00:00:00.4270000 -- Status: Successful 
Count: 1 

Date    Computer  Threat     ThreatStatus 
----    --------  ------     ------------ 
29/06/2017 12:55:37 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 11:48:28 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 10:55:37 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 09:55:38 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 08:48:28 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 08:48:28 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 07:55:37 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 07:55:37 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 06:48:28 xxx.local  Virus:ALisp/Bursted.DT Quarantined 
29/06/2017 06:48:28 xxx.local  Virus:ALisp/Bursted.DT Quarantined 

Quand je lance mon code d'automatisation, je reçois cette erreur

ConvertFrom-Json : The input object cannot be bound to any parameters for the command either because the command does 
not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. 
At line:164 char:33 
+ $OMSComputers = $Result.Value | ConvertFrom-Json 
+         ~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidArgument: ({ 
    "Computer"...ng": {} 
    } 
}:JObject) [ConvertFrom-Json], ParameterBindingException 
    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.ConvertFromJsonCommand 

Eh bien, mon erreur est ici

$OMSComputers = $Result.Value | ConvertFrom-Json 

Quand je regarde dans sa valeur, je reçois ce (juste pris une propriété dans la liste donnée par Result.Value $)

VALUEOUT: 

Name      : Computer 
Type      : Property 
HasValues     : True 
First      : {} 
Last      : {} 
Count      : 1 
Parent      : {Computer, Threat, ThreatStatus, __metadata} 
Root      : {Computer, Threat, ThreatStatus, __metadata} 
Next      : {} 
Previous     : 
Path      : Computer 
LineNumber     : 0 
LinePosition    : 0 
IsReadOnly     : False 
AllowNew     : True 
AllowEdit     : True 
AllowRemove    : True 
SupportsChangeNotification : True 
SupportsSearching   : False 
SupportsSorting   : False 
IsSorted     : False 
SortProperty    : 
SortDirection    : Ascending 
IsFixedSize    : False 
SyncRoot     : System.Object 
IsSynchronized    : False 

ISEE cette ligne

Keys      : {Computer, Threat, ThreatStatus, __metadata} 

j'ai essayé de l'analyser comme une hashtable, mais sans résultat.

Est-ce que quelqu'un a d'autres moyens créatifs de résoudre ce problème? Merci

Modifier: J'ai seulement passé ma fonction ici. Mais dans le script complet, je suis bien connecté et le module PS est déjà là (sinon la fonction échoue en me disant, le RG ne peut pas être trouvé, mais malgré, je clique et ajoute le module de votre lien). Si je regarde le contenu du résultat $ je reçois le résultat de la requête.

{ 
    "Computer": "xxx.local", 
    "Threat": "Virus:ALisp/Bursted.DT", 
    "ThreatStatus": "Quarantined", 
    "__metadata": { 
     "Type": "ProtectionStatus", 
     "TimeGenerated": "2017-06-29T10:55:37.77Z", 
     "highlighting": {} 
    } 
} 

quand je demande son type

Newtonsoft.Json.Linq.JObject 

donc j'importer le module Newtonsoft.Json et essayer de convertir ce genre de JSON, mais il est aussi défaut. Il semble que ma requête OMS fonctionne (j'ai un résultat dans $ Result) mais lorsque Automation tente de convertir avec 'ConvertFrom-Json', elle échoue.

#debug 
Write-Output "VALUEOUT:" 
Write-Output "Get-variable RESULT" 
Get-Variable Result -ValueOnly |format-list 
$OMSComputers = $Result.Value | ConvertFrom-Json 

Sortie:

VALUEOUT: 
    Get-variable RESULT 

    Id  : subscriptions/xxx/providers/Microsoft.Operatio 
       nalInsights/workspaces/xxx/search/xxx|10.1.0.27|2017-07-05T14-33-52Z 
    Metadata : Microsoft.Azure.Commands.OperationalInsights.Models.PSSearchMetadata 
    Error : 
    Value : {"Computer": "xxx.local" "Threat": "Virus:ALisp/Bursted.DT" "ThreatStatus": "Quarantined" 
       "__metadata": { 
       "Type": "ProtectionStatus", 
       "TimeGenerated": "2017-06-29T10:55:37.77Z", 
       "highlighting": {} 
       }, "Computer": "xxx.local" "Threat": "Virus:ALisp/Bursted.DT" "ThreatStatus": "Quarantined" 
       "__metadata": { 
       "Type": "ProtectionStatus", 
       "TimeGenerated": "2017-06-29T09:48:28.42Z", 
       "highlighting": {} 
       }, "Computer": "xxx.local" "Threat": "Virus:ALisp/Bursted.DT" "ThreatStatus": "Quarantined" 
       "__metadata": { 
       "Type": "ProtectionStatus", 
       "TimeGenerated": "2017-06-29T08:55:37.757Z", 
       "highlighting": {} 
       }, "Computer": "xxx.local" "Threat": "Virus:ALisp/Bursted.DT" "ThreatStatus": "Quarantined" 
       "__metadata": { 
       "Type": "ProtectionStatus", 
       "TimeGenerated": "2017-06-29T07:55:38.327Z", 
       "highlighting": {} 
       }...} 

ConvertFrom-Json : The input object cannot be bound to any parameters for the command either because the command does 

not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. 

At line:65 char:33 

+ $OMSComputers = $Result.Value | ConvertFrom-Json 

+         ~~~~~~~~~~~~~~~~ 

    + CategoryInfo   : InvalidArgument: ({ 

    "Computer"...ng": {} 

    } 

}:JObject) [ConvertFrom-Json], ParameterBindingException 

    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.ConvertFromJsonCommand 

Je ne comprends pas pourquoi le ConvertFrom-Json Fail:/

Répondre

0

compte d'automatisation Azure, il ne supporte pas le module d'importation en utilisant Import-Module AzureRm.OperationalInsights. La raison de votre erreur est $script:Result est null. Vous devez importer AzureRm.OperationalInsights dans votre compte Azure Automation. Veuillez vous référer aux étapes suivantes:

1.Ouvrez le link.

2.Cliquez sur Deploy to Azure Automation.

3.Supprimez Import-Module AzureRm.OperationalInsights dans votre runbook.

Remarque: Lorsque vous exécutez Get-AzureRmOperationalInsightsSearchResults, vous devez vous connecter à Azure dans le Runbook. Selon votre Runbook, il semble que vous n'ayez pas cette étape. Si vous ne le faites pas, veuillez l'ajouter à votre runbook.

Le runbook suivant fonctionne pour moi.

$connectionName = "AzureRunAsConnection" 
try 
{ 
    # Get the connection "AzureRunAsConnection " 
    $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName   

    "Logging in to Azure..." 
    Add-AzureRmAccount ` 
     -ServicePrincipal ` 
     -TenantId $servicePrincipalConnection.TenantId ` 
     -ApplicationId $servicePrincipalConnection.ApplicationId ` 
     -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
} 
catch { 
    if (!$servicePrincipalConnection) 
    { 
     $ErrorMessage = "Connection $connectionName not found." 
     throw $ErrorMessage 
    } else{ 
     Write-Error -Message $_.Exception 
     throw $_.Exception 
    } 
} 

## 
$omsRGname = "shuivm" 
$omsWorkspaceName = "shuitest" 
$omsQueryThreat = 'Type=ProtectionStatus ThreatStatusRank!=150 ThreatStatusRank!=470 | select Computer,Threat,ThreatStatus' 
$ArrayThreat = New-Object System.Collections.ArrayList 

function OmsRequest { 
    Param(
     [parameter(Position = 0, Mandatory = $true)] 
     $omsRG, 
     [parameter(Position = 1, Mandatory = $true)] 
     $omsWorkspace, 
     [parameter(Position = 2, Mandatory = $true)] 
     $omsQuery 
    ) 
    Process { 

     $error.clear() 
     $Result.clear 
     $script:Result = Get-AzureRmOperationalInsightsSearchResults -ResourceGroupName $omsRG -WorkspaceName $omsWorkspace -Query $omsQuery 
     $reqIdParts = $Result.Id.Split("/") 
     $reqId = $reqIdParts[$reqIdParts.Count - 1] 
     $wait = Get-Date 
     while ($Result.Metadata.Status -eq "Pending" -and $error.Count -eq 0) { 
      $Result = Get-AzureRmOperationalInsightsSearchResults -WorkspaceName $omsWorkspace -ResourceGroupName $omsRG -Id $reqId 
      #debug 
      $elapsedTime = $(get-date) - $wait 
      Write-Output "Elapsed: $elapsedTime -- Status: $($Result.Metadata.Status)" 
      Write-Output "Count: $($Result.Count)" 
     } 
    } 
} 

OmsRequest $omsRGname $omsWorkspaceName $omsQueryThreat 
#debug 
Write-Output "VALUEOUT:" $Result.Value 
# 
$OMSComputers = $Result.Value | ConvertFrom-Json 
if ($OMSComputers) { 
    foreach ($ThreatDetails in $OMSComputers) { 
     <#write "$(get-date($ThreatDetails.__metadata.TimeGenerated) -format G) - $($ThreatDetails.Computer) - $($ThreatDetails.Threat) - $($ThreatDetails.ThreatStatus)"#> 
     $ThDetails = [PSCustomObject] @{ 
      Date   = (get-date($ThreatDetails.__metadata.TimeGenerated) -format G); 
      Computer  = $ThreatDetails.Computer; 
      Threat  = $ThreatDetails.Threat; 
      ThreatStatus = $ThreatDetails.ThreatStatus; 
     } 
     $ArrayThreat.Add($ThDetails) |Out-Null 
    } 
} 
else {Write-Output "OK"} 

$ArrayThreat 
+0

Salut, juste essayé votre code, j'ai la même erreur avec "| ConvertFrom-Json "J'ai édité le premier message – Folk

+0

@Folk Je vérifie' $ Result.Value' n'est pas un format 'json', c'est un format de texte. Voulez-vous convertir en json? Si oui, vous devriez utiliser '$ Result.Value | ConvertTo-Json'.' ConvertTo-Json' est un fichier converti en un format json Si non, quel est le résultat '$ Result.Value' sur votre Power Shell local Est-ce le format' Json'? Si vous voulez seulement utiliser le format texte, je pense que vous n'avez pas besoin d'utiliser 'ConvertFrom-Json' –

0

J'ai exactement le même problème avec la commande: $Result.Value | ConvertFrom-Json

Ce comportement se produit à la fois dans un dossier d'exploitation d'automatisation et d'exécution au niveau local

Ceci est mon solution pour extraire le result.Value $ à partir d'une requête utilisant un ForEach et transmettant les valeurs à une hashtable:

$dynamicQuery = "* | measure count() by Type" 
$now = Get-Date 
$StartDateAndTime = $now.AddHours(-24).ToString("yyyy-MM-ddTHH:mm:ss") 

$EndDateAndTime = $now.ToString("yyyy-MM-ddTHH:mm:ss") 

$result = Get-AzureRmOperationalInsightsSearchResults ` 
-ResourceGroupName $ResourceGroupName ` 
-WorkspaceName $WorkSpaceName ` 
-Query $dynamicQuery ` 
-Start $StartDateAndTime ` 
-End $EndDateAndTime 

$queryResults = new-object System.Collections.Hashtable 

Foreach ($item in $result.value) 
{ 
$obj1 = $item["Type"].ToString() 
    $obj2= $item["AggregatedValue"].ToString() 
    [void]$queryResults.Add($obj1,$obj2) 
} 

Write-Output $queryResults 

Je l'ai ajouté comme un problème ici, car ce n'est pas comment le module est documenté et ce n'est pas une solution élégante: https://github.com/Azure/azure-powershell/issues/4256

+0

Bonjour, cela fonctionne à partir de mon ordinateur (win7 - PS5.1/4.0) [$ OMSComputers = $ Result.Value | ConvertFrom -Json], mais échoue dans Automation.Je montre le résultat de mon ordinateur dans mon premier poste.Je vais essayer votre solution, merci – Folk

+0

Bonjour @Folk - c'est un bug avec AzureRM.Operational.Insights 3.2.0 Les tests confirment que 3.0.1 renverra le bon JSON dans $ result.Value Heureusement, il ne semble pas que ce module plus ancien soit téléchargé vers Azure, il échoue toujours sur 'Extracting Activities' – thommonz

0

Merci pour votre aide :)

est ici le code de débogage je l'ai utilisé (et déjà ajouter à notre production MorningReport script) tandis que le module est cassé

###Query OMS for malware state 
#MorningMalwareDebug region Authentication 
Write-Verbose "" 
Write-Verbose "------------------------ Authentication ------------------------" 
Write-Verbose "Logging in to Azure ..." 
try { 
    $connectionName = "AzureRunAsConnection" 
    # Get the connection "AzureRunAsConnection " 
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName   
    $null = Add-AzureRmAccount ` 
     -ServicePrincipal ` 
     -TenantId $servicePrincipalConnection.TenantId ` 
     -ApplicationId $servicePrincipalConnection.ApplicationId ` 
     -SubscriptionName "xxxx" ` 
     -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 

    Write-Verbose "Successfully logged in to Azure." 
} 
catch { 
    if (!$servicePrincipalConnection) { 
     $ErrorMessage = "Connection $connectionName not found." 
     throw $ErrorMessage 
    } 
    else { 
     Write-Error -Message $_.Exception 
     throw $_.Exception 
    } 
} 
#MorningMalwareDebug endregion Authentication 
#### 
#MorningMalwareDebug region Function 
function OmsRequest { 
    Param(
     [parameter(Position = 0, Mandatory = $true)] 
     $omsRG, 
     [parameter(Position = 1, Mandatory = $true)] 
     $omsWorkspace, 
     [parameter(Position = 2, Mandatory = $true)] 
     $omsQuery 
    ) 
    Process { 
     Import-Module AzureRm.OperationalInsights 
     $error.clear() 
     $Result.clear 
     $script:Result = Get-AzureRmOperationalInsightsSearchResults -ResourceGroupName $omsRG -WorkspaceName $omsWorkspace -Query $omsQuery -Start $FromStartDate -End $ToEndDate 
     $reqIdParts = $Result.Id.Split("/") 
     $reqId = $reqIdParts[$reqIdParts.Count - 1] 
     $wait = Get-Date 
     while ($Result.Metadata.Status -eq "Pending" -and $error.Count -eq 0) { 
      $Result = Get-AzureRmOperationalInsightsSearchResults -WorkspaceName $omsWorkspace -ResourceGroupName $omsRG -Id $reqId 
      $elapsedTime = $(get-date) - $wait 
      Write-Output "Elapsed:" $elapsedTime "-- Status:" $Result.Metadata.Status 
     } 
    } 
} 
#MorningMalwareDebug endregion Function 
#### 
#MorningMalwareDebug region Variables 
$now = Get-Date 
$FromStartDate = $now.AddHours(-24).ToString("yyyy-MM-ddTHH:mm:ss") 
$ToEndDate = $now.ToString("yyyy-MM-ddTHH:mm:ss") 
$omsRGname = "xxxx" 
$omsWorkspaceName = "xxxx" 
$omsQueryThreat = 'Type=ProtectionStatus ThreatStatusRank!=150 ThreatStatusRank!=470 | select Computer,Threat,ThreatStatus' 
$ArrayThreat = New-Object System.Collections.ArrayList 
#MorningMalwareDebug endregion Variables 
#### 
#MorningMalwareDebug region Main 
OmsRequest $omsRGname $omsWorkspaceName $omsQueryThreat 
if ($Result.value) { 
    $ArrayThreat.clear() 
    Foreach ($ThreatDetails in $Result.value) { 
     $ThDetails = [PSCustomObject] @{ 
      Computer  = ($ThreatDetails["Computer"].ToString()).split('.')[0]; 
      Threat  = $ThreatDetails["Threat"].ToString(); 
      ThreatStatus = $ThreatDetails["ThreatStatus"].ToString(); 
     } 
     $ArrayThreat.Add($ThDetails) 
    } 
    Write-Output $ArrayThreat 
} 
else {write-output "Pas de menace"} 
#MorningMalwareDebug endregion Main 
#### 
#MorningMalwareDebug region BuildMail 
#MorningMalwareDebug endregion BuildMail 
#### 
#MorningMalwareDebug region SendMail 
#MorningMalwareDebug endregion SendMail