Real time analytics and PowerShell

I want to use a PowerShell script to imitate an IoT device that sends messages to and event hub in Azure. I’ve created the script below, but when I run it, it gives the error Send-AzEventHub’ is not recognized as the name of a cmdlet, function, script file, or operable program.

My PowerShell ISE is version 5 and PowerShell 7 is only a command line utility. And I can’t get PowerShell extension working in Visual Code.

So I tried the Cloud Shell in Azure portal, but I get the same message.

Anyone an idea how I can get a script going the simulated a IoT stream?

Install-Module Az.EventHub -Scope CurrentUser -Force -AllowClobber
Install-Module Az.Messaging.Eventhubs -Scope CurrentUser -Force -AllowClobber
Import-Module Az.EventHub -ErrorAction SilentlyContinue
Import-Module Az.Messaging.Eventhubs -ErrorAction SilentlyContinue

$EventHubConnectionString = “Endpoint=sb://ievxxxxbns.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=gMLcw9fGZvoxxxxxxxxxxxxxxxxxxxxxx1mb+AEhO6rvJM=”

$EventHubName = “ievxxxxhub”

$TruckIDs = @(“TRUCK-NL-001”, “TRUCK-BE-007”, “TRUCK-DE-042”, “TRUCK-FR-112”)

$SendIntervalSeconds = 5

$MinTemperature = -5.0 # Graden Celsius (bijv. voor gekoeld transport)
$MaxTemperature = 25.0 # Graden Celsius

Write-Host “Starten van temperatuur simulatie voor vrachtwagens…”
Write-Host “Event Hub Namespace Connection String (gedeeltelijk): $($EventHubConnectionString.Split(‘;’)[0])”
Write-Host “Event Hub Naam: $EventHubName”
Write-Host “Druk op CTRL+C om te stoppen.”
Write-Host “—”

try {
$i = 0
while ($true) {
$i++
Write-Host “`nCyclus $i - Data verzenden…”

    foreach ($TruckID in $TruckIDs) {
        # Simuleer temperatuur
        $CurrentTemperature = Get-Random -Minimum $MinTemperature -Maximum $MaxTemperature
        $CurrentTemperature = [Math]::Round($CurrentTemperature, 1) # Afronden op 1 decimaal

        # Simuleer een kleine variatie in locatie (optioneel)
        $Latitude = Get-Random -Minimum 50.0000 -Maximum 53.5000
        $Longitude = Get-Random -Minimum 3.5000 -Maximum 7.2000
        $Latitude = [Math]::Round($Latitude, 4)
        $Longitude = [Math]::Round($Longitude, 4)


        # Huidige tijdstip in UTC ISO 8601 formaat
        $Timestamp = (Get-Date).ToUniversalTime().ToString("o")

        # Creëer het data object (payload)
        $Payload = @{
            TruckId     = $TruckID
            Temperature = $CurrentTemperature
            Unit        = "Celsius"
            Timestamp   = $Timestamp
            Location    = @{
                Latitude = $Latitude
                Longitude = $Longitude
            }
            EventSource = "PowerShellSimulator"
        }

        # Converteer naar JSON
        $JsonPayload = $Payload | ConvertTo-Json -Compress

        try {
            # Verzend het bericht naar Event Hub
            # Send-AzEventHub verwacht een Namespace-level connection string en de Event Hub naam apart.
            Send-AzEventHub -ConnectionString $EventHubConnectionString -EventHubName $EventHubName -Message $JsonPayload
            Write-Host "[$Timestamp] Data voor $TruckID verzonden: Temp $($CurrentTemperature)°C. Payload: $JsonPayload"
        }
        catch {
            Write-Error "[$Timestamp] Fout bij verzenden data voor $TruckID naar Event Hub: $($_.Exception.Message)"
            # Optioneel: voeg hier logica toe om te stoppen of opnieuw te proberen na meerdere fouten
        }
    }

    Write-Host "---"
    Write-Host "Wachten voor $SendIntervalSeconds seconden tot de volgende cyclus..."
    Start-Sleep -Seconds $SendIntervalSeconds
}

}
catch {
Write-Error “Er is een onverwachte fout opgetreden in de hoofdlus: $($_.Exception.Message)”
}
finally {
Write-Host “Script gestopt.”
}

Hi, welcome to the forum :wave:

I can’t see Az.Messaging as part of the Az module, and the cmdlet Send-AzEventHub is also not part of the module as far as I can tell. Where does this code originate from?

I’ve not used IoT hubs with PowerShell, but looking at the Az module, I think you need to import Az.IoTHub and use Send-AzIotHubDevice2CloudMessage

Note: to properly format your quote, please use the </> button and paste your code between the three backticks. If you can’t see the </> button, it will be under the gear icon.

Thanks Matt for your message. Your proposed solution did’nt work. No errors anymore, but no data in my eventhub either.

This script was generated with AI. If you know a better place for me to look for a decent script, let me know.

I thought it might be AI. It’s hallucinating and offering a solution with modules and commands that don’t exist.

Looking at the code, I think we need to take a step back and figure out exactly what it is you’re trying to do before offering a solution.

For example, you say you want to simulate an IoT stream but there are elements of the code that don’t correspond with IoT stream usage, e.g. you’ve declared a namespace which isn’t necessary for an IoT stream. It looks more like a standard Event Hub.

Can you give us a bit more background about what you’re trying to achieve and what you’ve set up on the Azure side?

I find it odd that it’s called “hallucinating” when it comes from AI but if a human does it, we are lying. I think we should stop with this word play and call it like it is. AI is straight up making up lies. I just learned about a situation where AI “hallucinated” actual court cases for case law with names of real judges, just completely made up court cases.

1 Like

I dont use AI much, but have definitely seen this at times. The last time I recall I was asking for some javascript help it literally made up a method that was exactly what I was asking for. Had to laugh at that one. You have to make sure to do your due diligence with AI results.

2 Likes

Hi Matt,

As a trainer I need to train DP-700, Microsoft Fabric. One of the topics is real time analytics. I can use one of the samples in Fabric for a demonstration, but since the students have to do the same in an exercise, I was trying to demo something else.

So I want to create a event hub in Azure. Than I need a way to simulate a stream that is writing to that hub. That’s why I thought of doing it with PowerShell. Such a script I can easily start and keep running while I show what Fabric real time analytics does with it.

I haven’t found a cmdlet for this, but there is a PowerShell example here:

I modified it to use your sample data, and it sent the events successfully.

####################################################################
# Create SAS TOKEN FOR AZURE EVENT HUBS
####################################################################
# EventHubs Parameters
$EventHubsNamespace = ''
$EventHubsName = ''
$SharedAccessPolicyName = 'SendOnly'
$SharedAccessPolicyPrimaryKey = ''

# Create SAS Token
[Reflection.Assembly]::LoadWithPartialName('System.Web') | Out-Null
$URI = "$($EventHubsNamespace).servicebus.windows.net/$($EventHubsName)"
$Expires = ([DateTimeOffset]::Now.ToUnixTimeSeconds()) + 3600
$SignatureString = [System.Web.HttpUtility]::UrlEncode($URI) + "`n" + [string]$Expires
$HMACSHA256 = New-Object System.Security.Cryptography.HMACSHA256
$HMACSHA256.key = [Text.Encoding]::ASCII.GetBytes($SharedAccessPolicyPrimaryKey)
$SignatureBytes = $HMACSHA256.ComputeHash([Text.Encoding]::ASCII.GetBytes($SignatureString))
$SignatureBase64 = [Convert]::ToBase64String($SignatureBytes)
$SASToken = 'SharedAccessSignature sr=' + [System.Web.HttpUtility]::UrlEncode($URI) + '&sig=' + [System.Web.HttpUtility]::UrlEncode($SignatureBase64) + '&se=' + $Expires + '&skn=' + $SharedAccessPolicyName


####################################################################
# SEND DUMMY MESSAGES
####################################################################

# Determine URL and header
$RestAPI = "https://$($EventHubsNamespace).servicebus.windows.net/$($EventHubsName)/messages"

# API headers
$Headers = @{
    'Authorization' = $SASToken;
    'Content-Type'  = 'application/atom+xml;type=entry;charset=utf-8';
}

$TruckIDs = @('TRUCK-NL-001', 'TRUCK-BE-007', 'TRUCK-DE-042', 'TRUCK-FR-112')

$SendIntervalSeconds = 5

$MinTemperature = -5.0 # Graden Celsius (bijv. voor gekoeld transport)
$MaxTemperature = 25.0 # Graden Celsius

Write-Host 'Starten van temperatuur simulatie voor vrachtwagens…'
Write-Host "Event Hub Namespace Connection String (gedeeltelijk): $($EventHubConnectionString.Split(‘;’)[0])"
Write-Host "Event Hub Naam: $EventHubName"
Write-Host 'Druk op CTRL+C om te stoppen.'
Write-Host '—'

try {
    $i = 0
    while ($true) {
        $i++
        Write-Host "`nCyclus $i - Data verzenden…"

        foreach ($TruckID in $TruckIDs) {
            # Simuleer temperatuur
            $CurrentTemperature = Get-Random -Minimum $MinTemperature -Maximum $MaxTemperature
            $CurrentTemperature = [Math]::Round($CurrentTemperature, 1) # Afronden op 1 decimaal

            # Simuleer een kleine variatie in locatie (optioneel)
            $Latitude = Get-Random -Minimum 50.0000 -Maximum 53.5000
            $Longitude = Get-Random -Minimum 3.5000 -Maximum 7.2000
            $Latitude = [Math]::Round($Latitude, 4)
            $Longitude = [Math]::Round($Longitude, 4)

            # Huidige tijdstip in UTC ISO 8601 formaat
            $Timestamp = (Get-Date).ToUniversalTime().ToString('o')

            # Creëer het data object (payload)
            $Payload = @{
                TruckId     = $TruckID
                Temperature = $CurrentTemperature
                Unit        = 'Celsius'
                Timestamp   = $Timestamp
                Location    = @{
                    Latitude  = $Latitude
                    Longitude = $Longitude
                }
                EventSource = 'PowerShellSimulator'
            }

            # Converteer naar JSON
            $JsonPayload = $Payload | ConvertTo-Json -Compress

            try {
                # Verzend het bericht naar Event Hub
                # Send-AzEventHub verwacht een Namespace-level connection string en de Event Hub naam apart.
                Invoke-RestMethod -Uri $RestAPI -Method 'POST' -Headers $Headers -Body $JsonPayload
                Write-Host "[$Timestamp] Data voor $TruckID verzonden: Temp $($CurrentTemperature)°C. Payload: $JsonPayload"
            }
            catch {
                Write-Error "[$Timestamp] Fout bij verzenden data voor $TruckID naar Event Hub: $($_.Exception.Message)"
                # Optioneel: voeg hier logica toe om te stoppen of opnieuw te proberen na meerdere fouten
            }
        }

        Write-Host '---'
        Write-Host "Wachten voor $SendIntervalSeconds seconden tot de volgende cyclus..."
        Start-Sleep -Seconds $SendIntervalSeconds
    }
}
catch {
    Write-Error "Er is een onverwachte fout opgetreden in de hoofdlus: $($_.Exception.Message)"
}
finally {
    Write-Host 'Script gestopt.'
}
1 Like

Thanks Matt. This worked for me.