On Friday I released the latest version of the Pure1 PowerShell Module, version 126.96.36.199:
See release notes here:
So what is new in this release? Well a couple of things. First, it now support PowerShell core:
This now works in PowerShell 7 Core on Windows, Linux or Mac! To update or install:
Furthermore, there are a few enhancements/fixes:
- Multiple Pure1 Organizations
- Easy Refresh of Connections
- Improved debug support.
- Fixed issue where private key could not be read
The most significant feature is Core support, but before I get into that another new one is support for multiple Pure1 organizations. Previously, the Pure1 connection was stored in one variable, and if you wanted to use a different token or Pure1 org you needed to create the access token and pass it in each cmd–and that would still only look at the one organization. So if you have multiple orgs you needed to search through each one at a time.
So how does this work?
Well no different than before conceptually–either grab a certificate you created, or a create a new one with:
$cert = New-PureOneCertificate
Take that and pass the created certificate into:
$cert | Get-PureOnePublicKey
Then put the public key into Pure1 and retrieve the application ID and you can then authenticate with the certificate and the ID:
$cert |New-PureOneRestConnection -pureAppID pure1:apikey:OEWjK2EngkHgafFl
Now you can run commands:
Nothing changes here. But if you run it again with a different Pure1 organization, it does not override the connection, but instead authenticates both, so all queries will go to all organizations.
So let’s say I authenticate one Pure1 org and then pull all the arrays and put them into a variable and count the arrays:
Great so 17 arrays. Now authenticate a second one and do the same thing:
29! So it is now looking at all of the Pure1 organizations and returning all of the arrays.
Deep Dive: Pure1 Classes
To do this, I did a few things. First create a new class, call PureOneOrganization. This class has a few properties and methods. Also two sub-classes: UnixPureOneOrganization and WindowsPureOneOrganization. Depending on what you are using is what dictates what type is created. If you don’t care (and you don’t really need to know) skip ahead.
When you authenticate with New-PureOneRestConnection, it stores them in a global variable called $Global:PureOneConnections
This stores a bunch of properties, like the org ID, the role of the token (currently admin or read only), when the session expires (10 hours from creation), app ID, the token, and the certificate (windows) or private key/password (Linux/MacOS).
There are two methods (operations you an run on the object): SetDefault() and RefreshConnection().
SetDefault doesn’t really currently do much–the first connection you authenticate becomes the default, but the vast majority of Pure1 actions are read only–basically just pull information. So a default org to run operations on doesn’t make a lot of sense. Today the only change operation is tagging of arrays, and those arrays can only be in one org–so only running against the default doesn’t help. I built that into it for future use.
If you run it against and org, pass in $true or $false to make it default. Only one org at a time can be default.
But the RefreshConnection() operation might be useful. If you have a long running script, or something that runs constantly that polls or inserts data, the 10 hours might not be enough.
So if you look at a connection:
It currently expires at 5:30. If I run .RefreshConnection() on it:
It refreshes the token and I have a new expiration. In the future I plan to make this automatic when the New-PureOneOperation gets an expiration error.
Lastly, all cmdlets now allow you to pass in a specific organization object, so if you only want to query a specific org (or orgs), pass it in:
PowerShell Core Support
Up until this release the module somewhat worked on PowerShell core, but only on Windows. I have updated this release to not only fully support Core, but also on the other platforms (Linux and MacOS). The base requirements is that PowerShell 7 needs to be installed, and also OpenSSL (which should come native with all Unix platforms for the most part).
On Windows, the certificate management, and the RSA keys needed to sign the JSON Web Token were x509 type certificates. While these somewhat exist in Unix platforms, using direct PEM-encoded RSA private keys are the preferred option.
So the cmdlet to create the certificate has been updated to detect if it is running core on MacOS or Linux and will change behaviors. Instead of creating a certificate it will create a RSA private and public key pair in the working directory (or a directory of your choosing).
The cmdlet also requires that you assign a password to the private key–it will not accept non-encrypted keys.
So enter in a password as a secure string, a few ways to do this, but this is the simplest:
$password = Read-Host -AsSecureString
This will ask you to enter a password and store it in $password (must be 4 to 1023 characters).
Then run New-PureOneCertificate.
Note that New-PureOneCertificate and Get-PureOnePublicKey is a one-time operation. The next time you need to authenticate skip right to New-PureOneConnection documented below. Only redo this if you need to authenticate to different Pure1 organization or the key gets deleted.
New-PureOneCertificate -RsaPassword $password
This will return a table of the the newly created keys which you can store in a variable if you choose:
If you prefer to use a different directory (defaults to the working directory) you can specify one:
Next, you need to add the public key to Pure1. You can use the cmdlet Get-PureOnePublicKey to do that. Pass in the location of the private key and the private key password:
Get-PureOnePublicKey -PrivateKeyFileLocation /home/pureuser/test/PureOnePrivate.pem -RsaPassword $password
This can be a key created in the step above or one you created yourself through other means.
Now copy that key:
Withing Pure1 (pure1.purestorage.com) under API Registration add the key:
Copy the API key and return to PowerShell.
Now run the New-PureOneConnection to authenticate:
New-PureOneConnection -PrivateKeyFileLocation /home/pureuser/test/PureOnePrivate.pem -RsaPassword $password -PureAppID pure1:apikey:ah76Ts16SCp5DZXw
And you are done!
The full process is:
$password = Read-Host -AsSecureString<br>$keys = New-PureOneCertificate -RsaPassword $password Get-PureOnePublicKey -PrivateKeyFileLocation $keys.PrivateKey -RsaPassword $password New-PureOneConnection -PrivateKeyFileLocation $keys.PrivateKey -RsaPassword $password -PureAppID pure1:apikey:ah76Ts16SCp5DZXw
Once you have done the key creation once, it is only:
New-PureOneConnection -PrivateKeyFileLocation /home/pureuser/PureOnePrivate.pem -RsaPassword $password -PureAppID pure1:apikey:ah76Ts16SCp5DZXw
The connection, like on Windows is stored in the global variable $PureOneConnections:
This is a bit different class than the Windows version as instead of storing a certificate, it stores the password as a secure string and the path to the private key. So when you run the refresh it will use those to refresh the connection if needed:
Oh yes and you might note that the Pure1 get-array now also shows FQDNs of the arrays–it didn’t used to. The nice thing about a SaaS REST API is that you just get the new stuff. Enjoy!
There are more REST calls in Pure1 that are not supported in this module yet–so if you need to get something, just use New-PureOneOperation and pass in the PureOneToken parameter of the desired connection.
The command also supports queries and a json body if needed.
If you have feature requests or find bugs, add them here: