PowerShell
Synopsis
The VirtualMetric PowerShell module manages a DataStream tenant from the command line. Its 110 cmdlets cover directors, clusters, devices, targets, pipelines, routes, the Library and the Content Hub. They also run Bicep deployments, read the audit log, check the health of devices, directors and targets, run a pipeline's unit tests and read a source's events with a search.
The cmdlets follow the shape of Microsoft's Az module: Connect-VMetric, Get-VMetricContext, and Get/New/Set/Remove-VMetric<Type>. Objects flow through the pipeline, and -WhatIf shows what the deployment engine would actually change.
The module runs on PowerShell 7.2 or later on Windows, Linux and macOS. Windows PowerShell 5.1 is not supported. The same cmdlets run in the console's Cloud Shell, with no installation.
A PowerShell sign-in acts as you: your role and your access to tenants apply, and the audit log names you. It goes through the REST API, so it needs a plan that includes REST API access, exactly as API tokens do.
Installing the Module
From your VirtualMetric installation. The API serves the module that matches its own version, at GET /api/v1/cli/powershell/VirtualMetric.zip, without signing in. An air-gapped installation has it too. Use the API's address: the console's config.js names it (apiUrl), and where the console and the API share an origin it is the console's address.
$modules = ($env:PSModulePath -split [IO.Path]::PathSeparator)[0] # your user's module folder
Invoke-WebRequest https://api.example.com/api/v1/cli/powershell/VirtualMetric.zip -OutFile VirtualMetric.zip
Expand-Archive VirtualMetric.zip -DestinationPath $modules -Force
Import-Module VirtualMetric
On Windows, a zip downloaded with a browser is marked as coming from the internet. Unblock the files before importing:
Get-ChildItem "$modules/VirtualMetric" -Recurse | Unblock-File
From the PowerShell Gallery, once it is published there:
Install-Module VirtualMetric -Scope CurrentUser
The Gallery follows the product's releases, while the zip always holds the cmdlets of the server you download it from. Both carry the product's version, so Get-Module VirtualMetric tells you which release a copy came from.
Signing In
Connect-VMetric signs in with one of three methods:
| Method | Command | When to use it |
|---|---|---|
| Browser | Connect-VMetric -Uri <console or API> | The default |
| Device code | Connect-VMetric -Uri <console or API> -UseDeviceAuthentication | Over SSH, on Linux without a display, or whenever no browser opens |
| API token | Connect-VMetric -Uri <console or API> -ApiToken (Get-Secret VMetricToken) | Automation |
Give either the console's address or the API's. They are often on different origins, and the module finds one from the other. Only https is accepted, except to this machine.
On VirtualMetric's own cloud, name the environment instead of an address. -Environment takes eu-west, us-east, aus-east, preprod or dev. With neither -Uri nor -Environment, Connect-VMetric signs in to the environment $env:VMETRIC_ENVIRONMENT names, so a profile can set a default. -Uri always wins over the variable, and -Uri with -Environment is refused.
Connect-VMetric -Environment eu-west
$env:VMETRIC_ENVIRONMENT = 'eu-west'; Connect-VMetric # the same
Browser
The browser opens on the console's authorize page (/cli/authorize). Sign in if you need to, choose a tenant, and click
The module waits on 127.0.0.1 for the browser's return, for up to 5 minutes. It checks the return with PKCE and a random state, so no other program can complete the sign-in in your place.
Device Code
PowerShell prints a code and the console's device page (/cli/device). Open that page on any device, sign in to the console, enter the eight-letter code (for example BCDF-GHJK), and click
A code lasts 15 minutes and can be used once.
API Token
For automation, pass an API token as a SecureString, from Microsoft.PowerShell.SecretManagement or Read-Host -AsSecureString. The token's own tenant and role apply, not yours, and it is never refreshed. Nothing is approved in the console.
After Signing In
If the console asks you to sign in while you are on one of the two approval pages, it brings you back to that page afterwards rather than to Home. This works in the same browser tab, within 15 minutes.
When it connects, the module prints the user and tenant it signed in as.
Approving a Sign-In
Both approval pages are titled
Both pages open with a warning: Connect-VMetric yourself, deny or cancel.
What the page verifies. The device page shows the 127.0.0.1 with a port.
Reported by the sign-in request (not verified). A separate box lists details that come from the request itself, so whoever started the sign-in can make them say anything. On the device page, these are the
The tenant. Choose the
The outcomes:
| Page | Outcome | What it means |
|---|---|---|
| Device | Approved. PowerShell works in the tenant you chose, as you. Close the tab and return to PowerShell. | |
| Device | PowerShell was not signed in, and the code no longer works | |
| Device | The code was used or ran out of time. Run Connect-VMetric again for a new one. | |
| Authorize | Authorized. The browser is handing the sign-in to PowerShell. Close the tab once PowerShell says it is connected. | |
| Authorize | PowerShell was not signed in, and the browser is telling it so | |
| Authorize | The link was made for another program, points outside this computer, is incomplete or changed, or has expired. Run Connect-VMetric again. |
Approving, denying and every sign-in that creates a session are recorded in the audit log.
Sessions and Tenants
A sign-in refreshes itself while you work and lasts up to 30 days. It is held in memory for the current PowerShell session only, so a new PowerShell window needs a new sign-in.
Get-VMetricContext # the console and API addresses, the account, the tenant; never a token
Get-VMetricTenant # the tenants you may use: main, MSSP subtenants, delegated
Set-VMetricContext -Tenant Fabrikam # switch, without signing in again
Connect-VMetric -Uri https://console.example.com -Tenant Fabrikam # sign in straight into a tenant
Disconnect-VMetric # revoke the sessions on the server and forget them
The tenants you can choose are the ones the console's own tenant switch lets you into: your main tenant, the subtenants you manage, and the tenants you hold an access grant for. A switch ends the session you leave, and a refused switch changes nothing.
Every session appears under PowerShell sessions in your Account Settings, where you can revoke it. A session ends when:
- you sign out with
Disconnect-VMetric - you revoke it from Account Settings
- you lose access to the session's tenant
- 30 days have passed since the sign-in
Every one of your PowerShell sessions, in every tenant, ends at once when your password is changed or reset, your role is changed, or your account is deactivated or deleted.
Signing out of the console does not end a PowerShell session. A PowerShell sign-in is independent of the console, as an az login is of the Azure portal.
When a session has ended, the next command reports Your session has ended. Run Connect-VMetric again.
Cmdlets
Get-Command -Module VirtualMetric lists the cmdlets, and Get-Help <cmdlet> -Full documents each one.
| Resources | Cmdlets |
|---|---|
| Directors, clusters, devices, targets, advanced routes, datasets, profiles | Get, New, Set, Remove, Enable, Disable |
| Pipelines and their children, quick routes | Get, New, Set, Remove |
| Library: grok patterns, schemas, lookups, scripts, samples, SNMP vendors | Get, New, Set, Remove |
| Vault secrets | Get, New, Set, Remove |
| Agents | Get |
| Pipeline staging | New-VMetricPipelineStaging, Sync-VMetricPipelineStaging [-EndStaging], Remove-VMetricPipelineStaging |
| Content Hub | Get-VMetricContentHubPack, Install-VMetricContentHubPack, Get-VMetricContentHubRoute, Install-VMetricContentHubRoute, Remove-VMetricContentHubRoute |
| Deployments | New-VMetricDeployment, Test-VMetricDeployment, Get-VMetricDeployment, Stop-VMetricDeployment, Export-VMetricTemplate |
| Audit log | Get-VMetricAuditLog |
| Pipeline unit tests | Get-VMetricPipelineTest, Test-VMetricPipeline |
| Health | Get-VMetricDeviceHealth, Get-VMetricDirectorHealth, Get-VMetricTargetHealth |
| Search | Get-VMetricSearchSource, Invoke-VMetricSearch |
- Get lists every item, or reads one by
-Id.-Namekeeps the one whose name matches exactly, ignoring case. - New, Set, Enable and Disable write through the deployment engine, one resource per deployment, exactly as a Bicep template or the console would. Each write is validated, permission-checked and audited, and appears in the console's Deploy history as
pwsh-<verb>-<type>-<name>. New refuses a name that already exists; use Set for that. Set changes only what you name and keeps the rest. - Remove deletes, and asks first.
Objects keep the API's field names. A device's own settings are copied onto the object, so a pipeline can filter on them. Every Unix-seconds timestamp has a local DateTime beside it, such as createdAt and CreatedAtTime.
Get-VMetricDevice | Where-Object protocol -eq udp | Set-VMetricDevice -Port 1514 -WhatIf
Get-VMetricDevice -Name fortigate-syslog | Format-List *
Get-VMetricAuditLog -ObjectType Device | Where-Object CreatedAtTime -gt (Get-Date).AddDays(-1)
Import-Csv listeners.csv | New-VMetricDevice -Type syslog -Director director-01 -WhatIf
A pipeline write from PowerShell or the REST API is committed and merged directly, so it goes live without a review. Add -Review to New-VMetricPipeline, Set-VMetricPipeline, New-VMetricPipelineChild or Set-VMetricPipelineChild to leave the commit pending for a reviewer instead. See Source Control.
Changing a Field
Set has parameters for what most resources share (-Status, -Pipeline, -Description). On devices, it also has parameters for what every listener has (-Port, -Protocol, -Address).
-Status active|passive on Set-VMetricDirector, Set-VMetricCluster, Set-VMetricDevice, Set-VMetricTarget, Set-VMetricAdvancedRoute, Set-VMetricDataset and Set-VMetricProfile does the same as the matching Enable- or Disable- cmdlet.
To change any other field Format-List * shows on a device or a target, name it with -Field and give its new value with -Value. This includes the device's or target's own settings:
Set-VMetricDevice fortigate-syslog -Status passive # the same as Disable-VMetricDevice
Set-VMetricDevice fortigate-syslog -Field framing -Value rfc6587 # one of the device's own settings
Set-VMetricDevice fortigate-syslog -Field tls.status -Value true # a field inside an object, dotted
Get-VMetricTarget -Type splunk | Set-VMetricTarget -Field batch_size -Value 1000 -WhatIf
- A field name is matched ignoring case, as
Format-List *shows it. Press Tab after-Fieldto list the resource's fields. - A nested field is named with dots, as in
tls.status. - The value takes the type of the value it replaces.
-Value falseis a boolean where the setting is true or false, and-Value 6515is a number where the setting is a number. A value that does not fit is refused before anything is sent. -Fieldsets one value. An object or a list, such astls, is refused. Name a field inside it instead.
A Set that names nothing to change is refused. Editing an object and piping it back, as in $d.port = 6515; $d | Set-VMetricDevice, changes nothing, because only parameters are read. Use -Field instead.
WhatIf and Confirm
-WhatIf on New, Set, Enable and Disable asks the deployment engine for a preview, prints every property it would change, and changes nothing:
What if: Update device 'fortigate-syslog':
properties.properties.port: 514 → 1514
-Confirm shows the same preview and asks before writing. A change the engine would refuse, such as a device's type, is reported as an error before anything is asked. A secret you give shows as *** in the preview.
Secrets
Give secrets as SecureStrings, for example -Value (Read-Host -AsSecureString). The module reads a secret you give only to send it in the request, and never writes it to any output, error, verbose line or transcript.
A value a write returns only once, such as a new director's API key and install script, is the exception: it is added to the object the cmdlet emits (ApiKey, InstallScript), with a warning. Copy it then, because it cannot be shown again. It is a credential, so store it as a secret, and do not display it while a transcript is recording or write it to a log.
Deployments and Jobs
New-VMetricDeployment -TemplateFile ./firewall.bicep -TemplateParameterObject @{ port = 1514 } -WhatIf
$job = New-VMetricDeployment -TemplateFile ./fleet.bicep -AsJob; $job | Receive-Job -Wait
Get-VMetricDeployment -Status running | Stop-VMetricDeployment
Get-VMetricDevice -Name fortigate-syslog | Export-VMetricTemplate -Path ./fortigate.bicep
New-VMetricDeployment validates the template first and shows the engine's what-if with -WhatIf. Then it waits for the deployment and shows its progress (the default), returns at once with -NoWait, or runs as a thread job with -AsJob.
A job uses your session. If you sign out or switch tenants, the job stops following its deployment, but the deployment goes on. See Templates for the template language.
Health
Get-VMetricDeviceHealth, Get-VMetricDirectorHealth and Get-VMetricTargetHealth read the health of one resource, by -Name or piped from its Get cmdlet. The answer is what the console's health view shows: the connection, CPU and memory use, the totals, and a series.
Get-VMetricDeviceHealth fortigate-syslog
Get-VMetricDevice | Get-VMetricDeviceHealth | Where-Object errorRate -gt 0.01 | Select-Object name, eventsIn, errorRate
Get-VMetricDirector | Get-VMetricDirectorHealth | Format-Table name, stateName, cpuPct, memPct, errorRate
- The window is the last hour.
-Fromand-Totake Unix seconds. -Intervalis the width of a series bucket, in seconds. Left out, it is picked for the window.- A rate is a fraction of the events received, so
0.01is one in a hundred. - A reading nothing reported is empty, never zero.
Pipeline Tests
Get-VMetricPipelineTest <pipeline> lists a pipeline's unit tests, with their last status. Test-VMetricPipeline <pipeline> runs them all, or only the ones named with -Test, and emits one result per test.
Test-VMetricPipeline fw_syslog
Get-VMetricPipeline | Test-VMetricPipeline | Where-Object status -ne passed
Each result has a status of passed, failed or error. A test that fails is a result, not an error, so a script checks status. A run changes no pipeline and no test.
Search
Get-VMetricSearchSource lists what a search can read. Invoke-VMetricSearch reads the rows of one source, named with -Dataset or -Device, or piped from Get-VMetricSearchSource.
Invoke-VMetricSearch 'SecurityEvent | where TimeGenerated > ago(1d) and EventID == 4625' -Dataset 'DC security'
Get-VMetricSearchSource fw-01 | Invoke-VMetricSearch -CaptureSeconds 30 | Select-Object TimeGenerated, HostName, SyslogMessage
The query is a filter, not a program. The source applies the time range and the filters it can, and nothing runs the rest of the query.
| Source | Applied at the source |
|---|---|
| Windows Security Events dataset | The time range on TimeGenerated, EventID, Computer |
| Windows File Logs dataset | The time range on TimeGenerated, Computer, FilePath |
| Syslog device | Nothing: a capture reads the stream forward |
The rest of the query, such as summarize, project or a where condition the source cannot apply, is not run. The cmdlet writes a warning that says what was not applied, and returns the rows the source returned. Shape the rows in PowerShell instead, with Where-Object, Group-Object and Select-Object.
The console's Search page runs the whole query. The cmdlet and the REST API return the source's rows.
- Without
-Fromand-To, a dataset's range is the one the query asks for, such asTimeGenerated > ago(1d), or else the last hour. A range spans 31 days at most. - The rows stop at
-Limit: 5000 by default, at most 5000 from a device and 10000 from a dataset. -Pipelinesends every event through a pipeline first, and the rows are then its output.- A query that is not valid KQL is refused.
Permissions
A PowerShell session carries your own permissions, with no permission key of its own. Each cmdlet needs what the matching console action needs:
| Cmdlets | Permissions |
|---|---|
Get-VMetricDeviceHealth | STATS_READ, DEVICE_READ, DIRECTOR_READ, TARGET_READ, PIPELINE_READ |
Get-VMetricDirectorHealth | STATS_READ, DIRECTOR_READ, DEVICE_READ, TARGET_READ |
Get-VMetricTargetHealth | STATS_READ, TARGET_READ |
Get-VMetricPipelineTest, Test-VMetricPipeline | PIPELINE_READ |
Get-VMetricSearchSource, Invoke-VMetricSearch | LIVEDATA_READ |
See REST API Access for the routes these cmdlets call.
Troubleshooting
| Symptom | What to do |
|---|---|
Connect-VMetric is not recognized | Run PowerShell 7.2 or later (pwsh), and check that the module is in a folder of $env:PSModulePath |
| No browser window opens (WSL, a remote desktop) | Use -UseDeviceAuthentication |
Could not listen on 127.0.0.1 | Something blocks local listening sockets. Use -UseDeviceAuthentication. |
| A certificate error | Install the certificate authority of the console's certificate. -SkipCertificateCheck is for a test server only. |
| 403 with an edition or feature code | The tenant's plan does not include REST API access, which PowerShell needs |
Your session has ended | The session was revoked, expired after 30 days, or lost access to the tenant. Run Connect-VMetric again. |
Another deployment is running | One deployment runs at a time per organization, and the module already waited 30 seconds. Try again when it ends. |
| What did it send? | Add -Verbose. Every request and its status is shown, never a token or a body. |
An error carries the API's error code and a trace ID. Quote the trace ID to support.