[metrics-team] Fwd: Tor Metrics PowerShell Module

Karsten Loesing karsten at torproject.org
Wed Nov 8 09:52:19 UTC 2017


(Forwarding to the list with Luke's permission.)

Hi Luke,

I don't have a PowerShell available, nor am I the typical user of such a
tool.

But I hope that others on this list have better feedback on possible use
cases. In particular the recent work on metrics-bot seems very related.

I'd say let's wait until the module is on GitHub and has seen some
initial usage and then put it together with a short description on the
Services page:

https://metrics.torproject.org/services.html

Want to ping us in a week or two about adding it?

Regarding Tor Weekly News, unfortunately there have not been new issues
of that for a while now. You could instead send a message to tor-relays@
to inform relay operators of the new tool and ask them to send you some
more feedback.

All the best,
Karsten


-------- Forwarded Message --------
Subject: Tor Metrics PowerShell Module
Date: Wed, 8 Nov 2017 14:08:25 +1100
From: Luke Millanta <lmillanta at gmail.com>
To: Karsten Loesing <karsten at torproject.org>

Hi Karsten,

A few years ago we spoke while I was developing OnionView, a service which
uses Onionoo to plot the location of Tor relay nodes on a map of the world.

I got a little bored over the weekend and decided to help one of my Twitter
followers out. They were saying it would be cool if they could query Tor
nodes via the PowerShell command line. With a beer in hand, I set about
writing a fairly simple PowerShell module that allows users to query data
from Onionoo via the command line. This module is attached, simply rename
.txt to .psm1 if you would like to test. I plan to have this module up on
Github shortly but for now this will do.

Some example commands:
- Get-TorStatsCount - returns an object with a Count of relays and bridges
- Get-TorRelayStats - returns a list of relay objects with all basic info
about the relay (platform, ip address etc.)
- Get-TorBridgeStats - returns a list of bridge objects with all basic info
about the bridge (platform, ip address etc.)

- Filter Example: Get-TorBridgeStats | Where-Object {$_.nickname -eq
"string"}

The user is able to filter for a specific bridge or relay using any object
as listed here: https://metrics.torproject.org/onionoo.html

I have also attached a couple of screenshots of the module in action.

I was hoping you could do two things:

1. Provide me with some feedback.
2. Possibly get this noted in the Tor Weekly News, similar to how OnionView
was listed. This will be the best way to get the word out to the Tor
community.

Looking forward to hearing from you.

Regards,
Luke

-------------- next part --------------
<#
    .SYNOPSIS
    Name: tormetrics.psm1
    Get information from onionoo.torproject.org API
    
    .DESCRIPTION
    This module allows the user to query information about tor relays and bridges
    from onionoo.torproject.org API
    It features a caching mechanism so that it doesn't overburden the API.
    To get fresh results use the -FreshResults switch parameter

    .PARAMETER InitialDirectory
    [switch] FreshResults - get a fresh set of results from the API
	
    .NOTES
	Release Date: 2017-11-03
    Author: Luke Millanta

    .EXAMPLE
    Get-TorStats - Returns an object that contains relays and bridges properties
    The first time it runs it gets the results from the API and caches them locally
    On subsequent runs it will use the cached results.
    To force the command to get fresh results use the -FreshResults parameter

	Get-TorStatsCount - returns an object with a Count of relays and bridges
    Get-TorRelayStats - returns a list of relay objects
    Get-TorBridgeStats - returns a list of bridge objects

	Filter Example: Get-TorBridgeStats | Where-Object {$_.nickname -eq "string"}
#>

$APIRootURL = 'https://onionoo.torproject.org/details'
$APIFields = 'nickname,host_name,or_addresses,country_name,latitude,longitude,platform,flags'
$CacheFile = "$env:TEMP\$([guid]::NewGuid())-onionoo.torproject.xml"
#Remove previous cache
Get-ChildItem -File -Path "$env:TEMP" | Where-Object {$_.Name -like "*onionoo.torproject.xml"} | Remove-Item -Force
function Get-TorStats {
    [CmdletBinding()]
    param (
        [switch]$FreshResults
    )

    begin {
        
    }

    process {
        $FullAPIURL = $APIRootURL# + '?fields=' + $APIFields
        try {
            if ($(Test-Path -Path $CacheFile) -and !$FreshResults) {
                Write-Host "Loading stats from cache $CacheFile" -ForegroundColor Yellow
                $Results = Import-Clixml $CacheFile
            }
            else {
                Write-Host "Loading fresh results"  -ForegroundColor Green
                $Results = Invoke-RestMethod -Uri $FullAPIURL
                $Results | Export-Clixml $CacheFile -Force    
            }
        }
        catch {
            Write-Error $_.Exception
            Exit -1
        }
        return $Results
    }

    end {
    }
}

function Get-TorStatsCount {
    [CmdletBinding()]
    param (
        [switch]$FreshResults
    )
    if ($FreshResults) { 
        $Stats = Get-TorStats -FreshResults  
    }
    else { 
        $Stats = Get-TorStats 
    }
    $RelayCount = $Stats.relays.Count
    $BridgeCount = $Stats.bridges.Count
    $Results = @{
        Relays  = $RelayCount;
        Bridges = $BridgeCount;
    }
    return New-Object psobject -Property $Results
}


function Get-TorRelayStats {
    [CmdletBinding()]
    param (
        [switch]$FreshResults
    )
    if ($FreshResults) { 
        $Stats = Get-TorStats -FreshResults  
    }
    else { 
        $Stats = Get-TorStats 
    }
    $Relays = $Stats.relays
    $Results = @()
    foreach ($Relay in $Relays){
        $Results += New-Object psobject -Property $([ordered]@{
            Nickname = $Relay.nickname;
            'Host Name' = $Relay.host_name;
            'Primary Address' = $($Relay.or_addresses -join ',');
            'Country Name' = $Relay.country_name;
            Latitude = $Relay.latitude;
            Longitude = $Relay.longitude;
            Platform = $Relay.platform;
            'Exit Node' = if($Relay.flags.Contains('Exit')) { 'Yes' }  else { 'No' };
        })
    }
    return $Results 
}

function Get-TorBridgeStats {
    [CmdletBinding()]
    param (
        [switch]$FreshResults
    )
    if ($FreshResults) { 
        $Stats = Get-TorStats -FreshResults  
    }
    else { 
        $Stats = Get-TorStats 
    }
    $Bridges = $Stats.bridges
    $Results = @()
    foreach ($Bridge in $Bridges){
        $Results += New-Object psobject -Property $([ordered]@{
            Nickname = $Bridge.nickname;
            'Primary Address' = $($Bridge.or_addresses -join ',');
            Platform = $Bridge.platform;
        })
    }
    return $Results 
}
Export-ModuleMember -Function Get-TorStats
Export-ModuleMember -Function Get-TorStatsCount
Export-ModuleMember -Function Get-TorRelayStats
Export-ModuleMember -Function Get-TorBridgeStats
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 1 - Tor Relay Data (List A Specific Number Of Relays).png
Type: image/png
Size: 27234 bytes
Desc: not available
URL: <http://lists.torproject.org/pipermail/metrics-team/attachments/20171108/77bbd8da/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 2 - Tor Relay Data (Finding Specific Relay).png
Type: image/png
Size: 20707 bytes
Desc: not available
URL: <http://lists.torproject.org/pipermail/metrics-team/attachments/20171108/77bbd8da/attachment-0003.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 528 bytes
Desc: OpenPGP digital signature
URL: <http://lists.torproject.org/pipermail/metrics-team/attachments/20171108/77bbd8da/attachment-0001.sig>


More information about the metrics-team mailing list