macOSにPowerShellをインストール、ついでに外部パッケージ(AWSPowershell.NetCore)もインストール

普段、職場やプライベートでAWSを利用する場合、Windowsマシンでaws-cliではなく[AWSPowerShell](https://aws.amazon.com/jp/powershell/)(aws-cliのPowerShell版)を利用しています。 ~~自宅のブレーカーが落ちてWindowsマシンが逝ってしまったため、やむを得ず~~ サブ機のMacBookでも同じ環境でAWSを使えたらいいな、と思い、OSS/クロスプラットフォーム化した[PowerShell](https://github.com/PowerShell/PowerShell)およびその上で稼働する[AWSPowerShell.NetCore](https://www.powershellgallery.com/packages/AWSPowerShell.NetCore/)をmacOSに入れてみました。以下、環境構築時の作業メモです。


# 前提環境

- macOS Sierra
- homebrewインストール済
- homebrew-caskインストール済

# 環境構築手順

## openssl & curl (by homebrew) インストール

macOSに同梱されているopensslはApple社独自開発のもので、一般的なLinuxディストリビューション等で利用されているopensslとは別物のようです。PowerShellは後者の方が相性がいいようなので、homebrewで後者に相当するものをインストールします。


```shell-session
wukann@mac ~$ brew install openssl
wukann@mac ~$ brew install curl --with-openssl
```

- https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md#openssl

>.NET Core requires Homebrew's OpenSSL because the "OpenSSL" system libraries on macOS are not OpenSSL, as Apple deprecated OpenSSL in favor of their own libraries. This requirement is not a hard requirement for all of PowerShell; however, most networking functions (such as Invoke-WebRequest) do require OpenSSL to work properly.

### 蛇足：AppleとOpenSSL

AppleがOpenSSLを利用しなくなった経緯についてはこちら↓を参照。

- [AppleのデバイスはなぜHeartbleedの被害を免れたのか？](http://xiaolongchakan.com/archives/4049143.html)

## PowerShellインストール

macOS向けのインストーラもあるようですが、今回はhomebrew-caskを利用します。

```shell-session:PowerShellインストール
wukann@mac ~$ brew cask install powershell
==> Caveats
A OpenSSL-backed libcurl is required for custom handling of certificates.
This is rarely needed, but you can install it with
  brew install curl --with-openssl
See https://github.com/PowerShell/PowerShell/issues/2211

==> Satisfying dependencies
==> Installing Formula dependencies from Homebrew
openssl ... already installed
complete
==> Downloading https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/powershell-6.0.0-alpha.14.pkg
######################################################################## 100.0%
==> Verifying checksum for Cask powershell
==> Running installer for powershell; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are ignored.
Password:
==> installer: Package name is powershell-6.0.0-alpha.14
==> installer: Installing at base path /
==> installer: The install was successful.
🍺  powershell was successfully installed!
```

一応、インストールされていることを確認。

```shell-session:PowerShellインストール確認
wukann@mac ~$ which powershell
/usr/local/bin/powershell
```

## AWSPowershell.NetCoreインストール

PowerShellにもパッケージ(モジュール）管理機能「[PowerShellGet](https://msdn.microsoft.com/en-us/powershell/reference/5.0/powershellget/powershellget)」があります。今回インストールしたPowerShell v6には最初から入っているようです。これを利用してAWSPowerShell.NetCoreをインストールします。

### PowerShellセッション起動

ここからはmacOSのshellセッションからPowerShellセッションを起動し、その上でPowerShellコマンド操作をします。

```shell-session:PowerShellセッション起動
wukann@mac ~$ powershell
PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS /Users/wukann>
```

### PowerShellリポジトリ設定(PSGallery)

PowerShellGetでモジュールをインストールする場合、事前にモジュールを公開しているリポジトリを登録する必要があります。今回インストールするAWSPowerShell.NetCoreは、Microsoft公式の[PowerShell Gallery(PSGallery)](https://www.powershellgallery.com/)で公開されています。
登録済みリポジトリの情報は`Get-PSRepository`コマンドで取得できます。

```ps1:登録済みPowerShellリポジトリ確認
PS /Users/wukann> Get-PSRepository

Name                      InstallationPolicy   SourceLocation
----                      ------------------   --------------
PSGallery                 Untrusted            https://www.powershellgallery.com/api/v2/

```

PowerShell Gallery(PSGallery)は最初から登録されていますが、`InstallationPolicy`が`Untrusted`に設定されています。このままでもPSGalleryからモジュールをインストールできますが、インストールの度に「信頼できなリポジトリからモジュールをインストールしますか？」という確認メッセージにY/N対応する必要があります。
今回はPSGalleryを「信頼済みのリポジトリ」として設定します。

```ps1:PSGalleryを信頼済みリポジトリに設定
PS /Users/wukann> Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
```

設定が反映されていることを確認。

```ps1:PSGallery設定確認
PS /Users/wukann> Get-PSRepository

Name                      InstallationPolicy   SourceLocation
----                      ------------------   --------------
PSGallery                 Trusted              https://www.powershellgallery.com/api/v2/
```

### AWSPowershell.NetCoreインストール

リポジトリの設定が済んだところで、`Install-Module`コマンドでAWSPowerShell.NetCoreをインストールします。

```ps1:AWSPowerShell.NetCoreインストール
PS /Users/wukann> Install-Module -Name AWSPowerShell.NetCore -Scope CurrentUser
```

念のため、`Get-InstalledModule`コマンドでインストール済みモジュールを確認。

```ps1:インストール済みモジュールの確認
PS /Users/wukann> Get-InstalledModule

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.1.2.0    PackageManagement                   https://powershel... PackageManagement (a.k.a. OneGet) is a new way to discover and in...
1.1.2.0    PowerShellGet                       https://powershel... PowerShell module with commands for discovering, installing, upda...
3.3.38.0   AWSPowerShell.NetCore               PSGallery            The AWS Tools for PowerShell Core lets developers and administrat...


```

#### 補足・`-Scope`オプションなし or `-Scope AllUsers`を指定した場合

今回、`Install-Module`コマンドに`-Scope CurrentUser`オプションを付けてモジュールをインストールしました。このオプションがない場合、`-Scope AllUsers`がデフォルトで指定されます。んで、そうするとこの↓ようにエラーとなります。

```:-ScopeをCurrentUserにしないで実行した場合
PS /Users/wukann> Install-Module -Name AWSPowerShell.NetCore -Scope AllUsers
PackageManagement\Install-Package : Administrator rights are required to install modules in '/usr/local/microsoft/powershell/6.0.0-alpha
.14/Modules'. Log on to the computer with an account that has Administrator rights, and then try again, or install '/Users/wukann/.local
/share/powershell/Modules' by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with
elevated rights (Run as Administrator).
At /usr/local/microsoft/powershell/6.0.0-alpha.14/Modules/PowerShellGet/1.1.2.0/PSModule.psm1:1809 char:21
+ ...          $null = PackageManagement\Install-Package @PSBoundParameters
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Exception
```

エラーメッセージを見る限りではPowerShellをsudoで起動すれば解決する気がしますが、「ここまでsudo無しで進めてこられたのにここだけsudoするのもなぁ…」ということで試していません。

### AWSPowershell.NetCoreインポート

**Notice:**ここで取り上げているモジュールのインポート(`Import-Module`)は、そのセッション内でのみ有効です。**powershellセッションを立ち上げ直した場合、再度インポートし直す必要があります。**
(この件に関する対処方法もいつか書ければ…)

ここまでの手順でAWSPowershell.NetCoreをインストールできましたが、この状態ではコマンドを利用できません。PowerShellセッションにモジュールが読み込まれていないためです。セッションに読み込まれ、利用可能なモジュールを確認するには、`Get-Module`コマンドを実行します。

```ps1:利用可能モジュール確認
PS /Users/wukann> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty...}
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     1.1.2.0    PackageManagement                   {Find-Package, Find-PackageProvider, Get-Package, Get-PackageProvider...}
Script     1.1.2.0    PowerShellGet                       {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}
Script     1.2        PSReadLine                          {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PSReadlineKeyHandle...
```

AWSPowershell.NetCoreが一覧になく、セッションに読み込まれていないことが確認できます。
モジュールをセッションに読み込むには、`Import-Module`を実行します。

```ps1:AWSPowerShell.NetCoreをPowerShellセッションに読み込む
PS /Users/wukann> Import-Module AWSPowerShell.NetCore
```

再度`Get-Module`コマンドを実行すると、AWSPowerShell.NetCoreがセッションに読み込まれたことが確認できます。

```ps1:Get-Module
PS /Users/wukann> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Binary     3.3.38.0   AWSPowerShell.NetCore               {Add-AASScalableTarget, Add-ACMCertificateTag, Add-ADSConfigurationItemsToA...
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty...}
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     1.1.2.0    PackageManagement                   {Find-Package, Find-PackageProvider, Get-Package, Get-PackageProvider...}
Script     1.1.2.0    PowerShellGet                       {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}
Script     1.2        PSReadLine                          {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PSReadlineKeyHandle...
```

実際にAWSPowerShell.NetCoreのコマンド(`Get-AWSPowerShellVersion`)を実行してみます。

```ps1:AWSPowerShell.NetCoreのコマンド実行
PS /Users/wukann> Get-AWSPowerShellVersion

AWS Tools for PowerShell Core
Version 3.3.38.0
Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Amazon Web Services SDK for .NET
Core Runtime Version 3.3.7.1
Copyright 2009-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Release notes: https://aws.amazon.com/releasenotes/PowerShell

This software includes third party software subject to the following copyrights:
- Logging from log4net, Apache License
[http://logging.apache.org/log4net/license.html]

```

ヨッシャ`(*´ω｀*)`