DEV Community

Cover image for A PowerShell currency conversion module
Mark Wragg
Mark Wragg

Posted on

A PowerShell currency conversion module

Two and a half years ago, I published a module to the PowerShell Gallery (the official Microsoft nuget repository for PowerShell scripts and modules) called CurrencyConverter. It came from another module I was working on called AzCostTools, in which I found I had a need to convert cost data that I was exporting out of Azure, into a local currency.

I originally blogged about this here: https://wragg.io/Perform-currency-conversion-with-PowerShell/

I wanted my AzCostTools module to be able to convert currency without the user having to sign up for a service and provide an API key, which led me to ExchangeRate-API, which provides an open API for currency conversion. CurrencyConverter uses this by default when converting Fiat (traditional, government-issued) currencies. This API refreshes daily, so you are not necessarily getting an exact exchange rate, but probably something that is close enough for general use. You can sign up to ExchangeRate-API if you want rates that are updated more frequently, and CurrencyConverter then supports this, you just provide your key via the -ApiKey parameter.

A short while after I published the module, someone raised an issue on GitHub asking if it could support Crypto currencies. ExchangeRate-API didn't offer this, but I discovered there was an open API for crypto currencies provided by CoinBase, so I added some additional cmdlets to wrap this API and allow for the conversion of these currencies.

Installation

Because the module is published to the PowerShell Gallery, you can install it using PowerShell's package management cmdlets:

Install-Module CurrencyConverter
Enter fullscreen mode Exit fullscreen mode

Or if you'd like to inspect the code directly, get it from GitHub.

The module is cross-platform, and has been tested on Windows (via Windows PowerShell and PowerShell 7), MacOS and Linux.

When I write a PowerShell module that wraps an API, I try to go beyond just returning the results of that API (because if that was all it did, you might as well just use Invoke-RestMethod). Although it is nice that PowerShell cmdlets allow you to extrapolate away the need for a user to know how to craft an API request (by providing parameter inputs instead), and also potentially finesse the results, returned as PowerShell objects that can then be further interrogated and manipulated.

Cmdlets

CurrencyConverter's initial cmdlets were as follows:

Convert-Currency

Convert-Currency allows you to convert a decimal value between two currencies, and returns a decimal value result. You can provide the value via the -Value parameter, or via the pipeline (which can be one or more values):

Convert-Currency -Value 100 -From USD -To GBP
Enter fullscreen mode Exit fullscreen mode
74.778300
Enter fullscreen mode Exit fullscreen mode
100,150,200 | Convert-Currency -From EUR -To JPY
Enter fullscreen mode Exit fullscreen mode
17584.342200
26376.513300
35168.684400
Enter fullscreen mode Exit fullscreen mode

Note that there's parameter validation on the -From and -To parameters with the codes for all of the supported currencies, so you can just tab through the various codes (and it will reject ones that are not supported).

Get-Currency

Get-Currency allows you to list all supported currencies:

Get-Currency
Enter fullscreen mode Exit fullscreen mode
Code Name                          Country
---- ----                          -------
AED  UAE Dirham                    United Arab Emirates
AFN  Afghan Afghani                Afghanistan
ALL  Albanian Lek                  Albania
AMD  Armenian Dram                 Armenia
ANG  Netherlands Antillian Guilder Netherlands Antilles
AOA  Angolan Kwanza                Angola
ARS  Argentine Peso                Argentina
...
Enter fullscreen mode Exit fullscreen mode

Which you can also use to discover a currency, by providing its code or country, for example:

Get-Currency -Country Singapore
Enter fullscreen mode Exit fullscreen mode
Code Name             Country
---- ----             -------
SGD  Singapore Dollar Singapore
Enter fullscreen mode Exit fullscreen mode

Format-Currency

Format-Currency returns a formatted string for a specified currency, including the currency symbol and rounded to two decimal places:

100 | Format-Currency -Currency USD
Enter fullscreen mode Exit fullscreen mode
$100.00
Enter fullscreen mode Exit fullscreen mode

Which you can chain from Convert-Currency (or any PowerShell script or command that returns a decimal value):

100 | Convert-Currency -From USD -To EUR | Format-Currency
Enter fullscreen mode Exit fullscreen mode
€89.21
Enter fullscreen mode Exit fullscreen mode

Note that the destination currency is included as a NoteProperty output from Convert-Currency which then allows it to be received as an input by Format-Currency and avoids it having to be specified manually. If you were just providing a value directly to Format-Currency then you'd need to specify the currency as an input:

100 | Format-Currency -Currency EUR
Enter fullscreen mode Exit fullscreen mode
€100.00
Enter fullscreen mode Exit fullscreen mode

In some cultures, the currency symbol is written after the amount. You can have Format-Currency do this by specifying -SymbolAtEnd:

100 | Format-Currency -Currency EUR -SymbolAtEnd
Enter fullscreen mode Exit fullscreen mode
100.00€
Enter fullscreen mode Exit fullscreen mode

Get-ExchangeRate

Get-ExchangeRate returns all (supported) exchange rates for a specified currency, or a specified exchange rate between two currencies:

Get-ExchangeRate -Currency USD
Enter fullscreen mode Exit fullscreen mode
result                : success
provider              : https://www.exchangerate-api.com
documentation         : https://www.exchangerate-api.com/docs/free
terms_of_use          : https://www.exchangerate-api.com/terms
time_last_update_unix : 1792972951
time_last_update_utc  : Mon, 26 Oct 2026 00:02:31 +0000
time_next_update_unix : 1793060461
time_next_update_utc  : Tue, 27 Oct 2026 00:21:01 +0000
time_eol_unix         : 0
base_code             : USD
rates                 : @{USD=1; AED=3.6725; AFN=64.826446; ...
Enter fullscreen mode Exit fullscreen mode

Note this returns the full API result, and the actual exchange rates are in the rates property when using the Open API, or conversion_rates when using an API key. If you just want to return the exchange rates (regardless of which API you're using) then specify -Rates:

Get-ExchangeRate -Currency GBP -Rates
Enter fullscreen mode Exit fullscreen mode
GBP : 1
AED : 4.910876
AFN : 86.523878
ALL : 108.353838
AMD : 482.971946
...
Enter fullscreen mode Exit fullscreen mode

Convert-CryptoCurrency, Get-CryptoCurrency, Get-CryptoExchangeRate

Crypto currencies have their own set of cmdlets, which work largely the same as those above, but against the Coinbase API. The cmdlets for these are:

  • Convert-CryptoCurrency - E.g 100 | Convert-CryptoCurrency -From GBP -To BTC
  • Get-CryptoCurrency - E.g Get-CryptoCurrency -Name Omni
  • Get-CryptoExchangeRate - E.g Get-CryptoExchangeRate -From GBP -To BTC

These allow conversion between Fiat and crypto currencies.

You can use Format-Currency with a crypto currency as well:

23.45 | Convert-CryptoCurrency -From BTC -To ETH | Format-Currency
Enter fullscreen mode Exit fullscreen mode
Ξ4,270.89
Enter fullscreen mode Exit fullscreen mode

Set-CurrencyDefault, Get-CurrencyDefault

Over the last week (with the aid of AI) I've added some extra functionality to the module. You can now save defaults via a new Set-CurrencyDefault cmdlet. This is useful if you're always converting to or from the same currencies (more likely from than to perhaps) or if you want to use an ExchangeRate-API API key and not provide it every time you use the cmdlet. For example:

Set-CurrencyDefault -From GBP -APIKey yourapikeyhere
Enter fullscreen mode Exit fullscreen mode

These are saved as JSON under your $Home directory in a folder called .currencyconverter, so that they will persist if/when you upgrade the module in the future. You can see what defaults you have saved by running Get-CurrencyDefault.

Once a default is set, you don't need to specify it anymore, so for example, this will now assume I am converting British Pounds (GBP):

100 | Convert-Currency -To USD
Enter fullscreen mode Exit fullscreen mode
133.728700
Enter fullscreen mode Exit fullscreen mode

Add-CurrencyMember

I also added a cmdlet called Add-CurrencyMember. This is inspired by PowerShell's built in Add-Member cmdlet, which you can use to append a new property to an existing PowerShell object. Add-CurrencyMember allows you to append one or more additional properties to an object that are a currency conversion of an existing object. This is useful where you have a set of data in PowerShell that you want to convert a currency column of data for. For example, say you have a collection of products (this could have been loaded from a CSV for example, but we'll just create a simple PowerShell array of objects as an example):

$Products = @(
  [pscustomobject]@{ Product = 'Widget'; Price = 100 }
  [pscustomobject]@{ Product = 'Gizmo'; Price = 75 }
  [pscustomobject]@{ Product = 'Sprocket'; Price = 125 }
)
Enter fullscreen mode Exit fullscreen mode

But the Price was USD, and you wanted it in EUR. You could do:

$Products | Add-CurrencyMember -Property Price -From USD -To EUR
$Products
Enter fullscreen mode Exit fullscreen mode
Product  Price PriceEUR
-------  ----- --------
Widget     100    89.21
Gizmo       75    66.91
Sprocket   125   111.52
Enter fullscreen mode Exit fullscreen mode

You can specify exactly what you want the new property name to be by providing -MemberName, and have the results returned immediately to the pipeline via -PassThru:

$Products | Add-CurrencyMember -Property Price -From USD -To EUR -MemberName PriceInEuro -PassThru
Enter fullscreen mode Exit fullscreen mode


plaintext

Product  Price PriceInEuro
-------  ----- -----------
Widget     100       89.21
Gizmo       75       66.91
Sprocket   125      111.52
Enter fullscreen mode Exit fullscreen mode

Note that while the default output is two decimal place, the PowerShell object does actually hold the exact decimal value:

Product     : Widget
Price       : 100
PriceInEuro : 89.21300

Product     : Gizmo
Price       : 75
PriceInEuro : 66.90975

Product     : Sprocket
Price       : 125
PriceInEuro : 111.51625
Enter fullscreen mode Exit fullscreen mode

ConvertTo-CurrencyTable

If you need to convert a value to multiple destination currencies, you can now do so via the ConvertTo-CurrencyTable cmdlet. This outputs a PowerShell object with each currencies value as a named property. For example:

100,150,200 | ConvertTo-CurrencyTable -From GBP -To USD,CAD,EUR
Enter fullscreen mode Exit fullscreen mode
   GBP    USD    CAD    EUR
   ---    ---    ---    ---
100.00 133.73 187.40 119.30
150.00 200.59 281.09 178.95
200.00 267.46 374.79 238.60
Enter fullscreen mode Exit fullscreen mode

Watch-ExchangeRate

If you want to monitor an exchange rate for change, there's now a Watch-ExchangeRate cmdlet. This will check a specified rate at a specified interval (60 seconds by default) and stop when it has moved up or down beyond a specified threshold. For example, this will monitor the British Pound to Bitcoin exchange rate, until it rises above 0.0000167346063796:

Watch-ExchangeRate -From GBP -To BTC -IntervalSeconds 5 -AboveThreshold 0.0000167346063796 | FT
Enter fullscreen mode Exit fullscreen mode
From To  Rate               Timestamp           Triggered
---- --  ----               ---------           ---------
GBP  BTC 0.0000167346063795 26/10/2026 14:32:05     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:12     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:17     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:23     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:29     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:35     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:42     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:48     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:53     False
GBP  BTC 0.0000167346063795 26/10/2026 14:32:58     False
GBP  BTC 0.0000167346063795 26/10/2026 14:33:04     False
GBP  BTC 0.0000167548698867 26/10/2026 14:33:10      True
Enter fullscreen mode Exit fullscreen mode

Obviously this is limited by how frequently the exchange rate API provides refreshed rates, and polling the open APIs too frequently may result in your being rate limited.

Historical Exchange Rates

Finally, Get-ExchangeRate, Convert-Currency, ConvertTo-CurrencyTable and Add-CurrencyMember now support a -Date parameter, which allows you to query a historical rate for a specified currency. This is only supported for Fiat currencies, as historical data comes only from ExchangeRate-API, and also requires you to specify an API key, because historical data is not accessible via the open API. For example:

Convert-Currency -Value 100 -From USD -To GBP -Date '2024-01-15' -ApiKey yourapikeystringhere
Enter fullscreen mode Exit fullscreen mode

Conclusion

This concludes this overview of the CurrencyConverter module. As previously mentioned, you can get it from the PowerShell Gallery or GitHub where there is also a detailed Wiki, which includes the PowerShell help output for each cmdlet giving further usage explanation and examples.

If you encounter any bugs or have any suggestions, please do log an issue:

Contributions are welcomed.

Top comments (0)