彷徨うITエンジニアの雑記

ITインフラ関連の雑記とか

Azure Bastion を Powershell からセットアップする

検証環境用にぱっと作って削除したかったのでPowershell化してみた。

注意点

以下を満たしていないとNew-AzBastionコマンドでエラーになる。

  • デプロイ先のサブネット名が 'AzureBastionSubnet' であること*1
  • セキュリティグループの要件を満たしていること*2

Bastionホストと関連リソースを作成する

# リソースグループ名
$rg_name = 'rg_test'

# Bationを展開するvNet名
$vnet_name = 'vnet_test'

# Bastion専用のサブネット
$sn_prefix = '10.0.254.0/24'

# Bastion専用のサブネットに設定するNSG名
$ngs_name = 'nsg_my_bastion'


## Bastionに設定するNSGを作成

# 自分の端末のグローバルIP
$myipinfo = Invoke-RestMethod http://ipinfo.io/json
$myip = $myipinfo.ip

# 自分の作業端末からBastionへのアクセスを許可するセキュリティグループを作成
$nsg = New-AzNetworkSecurityGroup -Name "$ngs_name" -Location 'Japan East' -ResourceGroupName "$rg_name"

# Inbound Rules
Add-AzNetworkSecurityRuleConfig -Name AllowMyPublicIPInbound -NetworkSecurityGroup $nsg -Direction Inbound -SourceAddressPrefix $myip -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 443 -Priority 100 -Protocol Tcp -Access Allow -Description "Allow Bastion from my public IP"
Add-AzNetworkSecurityRuleConfig -Name AllowGatewayManagerInbound -NetworkSecurityGroup $nsg -Direction Inbound -SourceAddressPrefix 'GatewayManager' -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 443 -Priority 101 -Protocol Tcp -Access Allow
Add-AzNetworkSecurityRuleConfig -Name AllowAzureLoadBlancerInbound -NetworkSecurityGroup $nsg -Direction Inbound -SourceAddressPrefix 'AzureLoadBalancer' -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 443 -Priority 102 -Protocol Tcp -Access Allow
Add-AzNetworkSecurityRuleConfig -Name AllowBastionHostCommunication -NetworkSecurityGroup $nsg -Direction Inbound -SourceAddressPrefix 'VirtualNetwork' -SourcePortRange * -DestinationAddressPrefix 'VirtualNetwork' -DestinationPortRange 8080,5701 -Priority 103 -Protocol * -Access Allow

# Outbound Rules
Add-AzNetworkSecurityRuleConfig -Name AllowAnyOutbound -NetworkSecurityGroup $nsg -Direction Outbound -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange * -Priority 200 -Protocol Tcp -Access Allow

# NSGにルールを適用
$nsg | Set-AzNetworkSecurityGroup


## vNetにBastion用のパブリック・サブネットを追加する

# vNetと作成したNSGをオブジェクトとして取得
$vnet = Get-AzVirtualNetwork -ResourceGroupName "$rg_name" | Where-Object {$_.Name -eq "$vnet_name"}
$nsg = Get-AzNetworkSecurityGroup -ResourceGroupName "$rg_name" -Name "$ngs_name"

# vNetに AzureBastionSubnet を追加
# インターネットからアクセスする場合は、ユーザ定義のルーティングテーブルは不要(パブリック・サブネットして構成)
Add-AzVirtualNetworkSubnetConfig -Name 'AzureBastionSubnet' -VirtualNetwork $vnet -AddressPrefix "$sn_prefix" -NetworkSecurityGroup $nsg
$vnet | Set-AzVirtualNetwork
$vnet = Get-AzVirtualNetwork -ResourceGroupName "$rg_name" | Where-Object {$_.Name -eq "$vnet_name"}

## Public IPを取得し、Bastionホストをデプロイする

# Publid IPのSKUはStandard
$publicip = New-AzPublicIpAddress -ResourceGroupName "$rg_name" -name "pubip_bastion" -location 'Japan East' -AllocationMethod Static -Sku Standard
# Bastionホストをデプロイ
$bastion = New-AzBastion -ResourceGroupName "$rg_name" -Name "myBastion" -PublicIpAddress $publicip -VirtualNetwork $vnet

Bastionホストと関連リソースを削除する

# リソースグループ名
$rg_name = 'rg_test'

# Bationを展開するvNet名
$vnet_name = 'vnet_test'

# Bastion専用のサブネットに設定するNSG名
$ngs_name = 'nsg_my_bastion'

Remove-AzBastion -ResourceGroupName "$rg_name" -Name "myBastion"
Remove-AzPublicIpAddress -Name "pubip_bastion" -ResourceGroupName "$rg_name"

$vnet = Get-AzVirtualNetwork -ResourceGroupName "$rg_name" -Name "$vnet_name"
Remove-AzVirtualNetworkSubnetConfig -Name 'AzureBastionSubnet' -VirtualNetwork $vnet
$vnet | Set-AzVirtualNetwork
Remove-AzNetworkSecurityGroup -ResourceGroupName "$rg_name" -Name "$ngs_name"

Powershellメモ3

簡易的な進捗カウンタをコンソールに表示したい

  • Write-Host -NoNewline ("`r" + "hogehoge") を使う
  • `r = CR(キャリッジ・リターン)でカーソルが左端に移動してコンソール表示を上書き
$N = 1000
for($i = 0; $i -lt $N; $i++) {

    # 進捗を10単位でコンソールに表示
    if(($i % 10) -eq 0){ Write-Host -NoNewline ("`r" + "PROGRESS: ${i} / ${N}") }

    # 処理
    $null = Start-Sleep -Milliseconds 100
}

UNIXシェルみたいに、コマンド出力をそのまま文字列として扱いたい

  • Out-String でオブジェクトを文字列の配列に変換
  • Stream オプションを付けないと1個の文字列の要素にまとめられてしまうので注意
> Get-ChildItem

    ディレクトリ: C:\Users\hoge


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2020/04/06     16:58                .android
d-----        2021/01/06     12:26                .Azure
d-r---        2020/06/14      0:39                3D Objects
d-----        2020/03/21     22:36                Apple
d-r---        2020/06/14      0:39                Contacts
d-----        2020/03/21     23:47                Documents
d-r---        2021/01/30      7:58                Downloads
d-r---        2020/06/14      0:39                Favorites
d-r---        2021/01/30      8:02                Google ドライブ
d-r---        2020/06/14      0:39                Links
d-r---        2020/06/14      0:39                Music
dar--l        2021/01/30      8:01                OneDrive
d-----        2020/03/22      1:00                Pictures
d-r---        2020/06/14      0:39                Saved Games
d-r---        2020/06/14      0:39                Searches
d-r---        2020/09/16     17:47                Videos


> Get-ChildItem | select-string 'Apple'

Apple


> Get-ChildItem | Out-String -Stream | select-string 'Apple'

d-----        2020/03/21     22:36                Apple

個人でMS Azureの実習を始める手順②

AzureをCLIから操作するためにPowershell環境を整備する。
使用頻度の高いモジュールとしてAz、AzureADPreview、MSOnlineをインストールする。

1. AzureのPowershellモジュールの種類

Module Name Current ver. Minimum Powershell ver. Desc.
Az 5.4.0 5.1 基本のAzureモジュールで、AzureRMモジュールの後継
MSOnline 1.1.183.57 2.0 AzureAD用のモジュールで、AzureAD v1モジュールとも呼ぶ
AzureAD 2.0.2.128 3.0 AzureAD用のモジュールで、MSOnlineモジュールの後継。AzureAD v2モジュールとも呼ぶ
AzureADPreview 2.0.2.129 3.0 AzureADモジュールのプレビュー版。同モジュールとの共存は不可

2. インストール要件確認

Powershell 5.1、.Net Framework 4.7.2 以上がインストールされていることを確認する。
Azモジュール5.4.0のシステム要件:
https://docs.microsoft.com/ja-jp/powershell/azure/install-az-ps?view=azps-5.4.0#requirements

# Powershellのバージョン
> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      18362  1171

# .Net Frameworkのバージョン
> Get-Item 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'


    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4


Name                           Property
----                           --------
Full                           CBS           : 1
                               Install       : 1
                               InstallPath   : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
                               Release       : 528040
                               Servicing     : 0
                               TargetVersion : 4.0.0
                               Version       : 4.8.03752

3. Powershellスクリプトの実行を許可する

管理者権限で以下のコマンドを実行する。
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

後続作業は一般ユーザ権限でOK。

4. Azモジュールをインストールする

詳細はAzureのドキュメント一覧の Install Azure Powershell を参照
Overview of Azure PowerShell | Microsoft Docs

認証プロキシが存在する場合は以下を参照(素晴らしい!)
qiita.com

# Onlineインストール
> Install-Module -Name Az -AllowClobber -Scope CurrentUser

# バージョン確認
> Get-InstalledModule -Name Az -AllVersions

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
5.4.0      Az                                  PSGallery            Microsoft Azure PowerShell - Cmdlets to manage r...

# 接続確認
> Connect-AzAccount

Account                       SubscriptionName TenantId                             Environment
-------                       ---------------- --------                             -----------
msazadmin@aabbcc12345.net MyAZSubscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx AzureCloud


アップデートは以下のコマンドを実行。
Update-Module -Name Az

アップデート後に古いバージョンが残っている場合は、古いバージョン削除して再インストールする。
Uninstall Azure PowerShell | Microsoft Docs

上記の方法で削除できない場合は $env:PSModulePath のどこかにある Az.* のフォルダをエクスプローラから削除する。
Scope=CurrentUser でインストールした場合は ~\ドキュメント\PowerShell\Modules 以下。

Offlineインストールの場合はGitHubからMSIをダウンロード可能。
https://github.com/Azure/azure-powershell

5. MSonlineモジュールをインストールする

最新版::
PowerShell Gallery | MSOnline 1.1.183.57

# Onlineインストール
> Install-Module -Name MSOnline -Scope CurrentUser

# バージョン
> Get-InstalledModule -Name MSOnline -AllVersions

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.1.183.57 MSOnline                            PSGallery            Microsoft Azure Active Directory Module for Wind...

# 接続確認
> Connect-MsolService
> Get-MsolUser -UserPrincipalName msazadmin@aabbcc12345.net

UserPrincipalName             DisplayName isLicensed
-----------------             ----------- ----------
msazadmin@aabbcc12345.net msazadmin   True

6. AzureAD用のPowershellモジュールをインストールする

最新版:
PowerShell Gallery | AzureADPreview 2.0.2.129

# Onlineインストール
> Install-Module -Name AzureADPreview -Scope CurrentUser

# バージョン
> Get-InstalledModule -Name AzureADPreview -AllVersions

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
2.0.2.129  AzureADPreview                      PSGallery            Azure Active Directory V2 Preview Module. ...

# 接続確認
> Connect-AzureAD

Account                       Environment TenantId                             TenantDomain        AccountType
-------                       ----------- --------                             ------------        -----------
msazadmin@aabbcc12345.net AzureCloud  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx aabbcc12345.net User

terraformの昔書いた.tfファイルを直す

バージョン0.12からシンタックスに変更が入ったため*1、昔書いた .tf を terraform plan するとSyntax Error出まくりで鬱になる。

実際に引っかかったエラーを記載しておく。

  • 関数の結果を取得するとき "${ }" で囲まない
<= 0.11 >= 0.12
"${cidrhost(var.private_subnet1_cidr, var.ad_params.private_ip_hostnum)}" cidrhost(var.private_subnet1_cidr, var.ad_params.private_ip_hostnum)
"${format("%s%s", "vpc_", var.vpc_name)}" format("%s%s", "vpc_", var.vpc_name)

<= 0.11 >= 0.12
roles = [ aws_iam_role.iam_role1.name ] role = aws_iam_role.iam_role1.name

AWS AppStream2.0を使った踏み台構築手順

AWS AppStream2.0 は Citrix XenApp や Microsoft RemoteApp みたいなソリューションのマネージドサービス。Windows Server上のアプリケーション画面やデスクトップを配信できる。

クライアント ➡ AppStream(ログインポータル・コネクションブローカー・リバプロ) ➡ 公開サーバ

このサービスでRDPクライアントやTeraterm等を公開すれば、パブリック・サブネットが無いシステムに対しても簡単に作業用の踏み台サーバを構築できる。
今まではAWS System ManagerやRDゲートウェイを構築していたので、導入や維持が面倒だった。
リッチクライアントも用意されているが、HTML5対応しているのも使い勝手がいい。

1. Image Builderで公開サーバのデプロイ元となるインスタンスを構成する

イメージビルダーで公開サーバのカスタマイズを行い、インスタンスのスナップショットを作成する。
実際にユーザがアクセスする先のインスタンス群は「フリート」と呼ばれ、このスナップショットからデプロイされる。

AWS Console: AppStream2.0 ➡ Images ➡ Image Builder ➡ Launch Image Builder

  • Choose Image

用途に従いベースイメージを選択する。
今回は Instance Family = General Purpose を選択して標準的なWindows Server 2019イメージを選択した。

Choose Image AppStream-Graphics-Design-WinServer2019-12-28-2020
  • Configure Image Builder
Name fumidai_win2019-001
Instance Type 2vCPU, 7.5GB RAM を選択
Endpoint Internet
クライアントから公開サーバへの接続をDirectConnect、VPNでクローズしたい場合のみエンドポイントを指定。VPC内のPrivateLink経由でAppStreamサービスにアクセスするネットワークフローになる。
IAM Role 設定しない*1

イメージのカスタマイズ作業をどのサブネットで実行するのか設定する。
この環境では、パブリック・サブネットとNATインスタンスがデプロイ済の為、イメージはプライベート・サブネットにデプロイすることにした。

Default Internet Access Off
イメージにPublicIPをセットする。NATが無いパブリック・サブネットにデプロイする場合はOnにする。
VPC デプロイ先のVPCを指定
Subnet プライベート・サブネットを指定
Security Group プライベート・サブネットに配置するので In/Out:Any Permit とした
  • Launch をクリックするとベースイメージがデプロイされる

2. イメージをカスタマイズする

AWS Console: AppStream2.0 ➡ Images ➡ Image Builder

15分程度でイメージのステータスが Peding ➡ Running に遷移する。

イメージを選択し [Connect] ボタンをクリックするとログオン画面が表示される。
Local Administrator でWindowsにログオンし、OSの設定変更やアプリのインストールを実行する。
この例では以下のカスタマイズを実施した。

  • Windows Server 2019の日本語化
    • Start -> Settings -> Time and language -> Language から日本語の言語パックをインストール
    • Powershellを管理者権限で実行し、以下のコマンドを実行
# タイムゾーン変更
Set-Timezone -Name "Tokyo Standard Time"
# リージョン
Set-WinHomeLocation -GeoId 122
# システムロケール
Set-WinSystemLocale -SystemLocale ja-JP
# 言語リストの優先順位
Set-WinUserLanguageList -LanguageList ja-JP,en-US -Force
# レガシーな言語バーを表示
Set-WinLanguageBarOption -UseLegacySwitchMode -UseLegacyLanguageBa
# OSのUI言語
Set-WinUILanguageOverride ja-JP
# デフォルト入力メソッド
Set-WinDefaultInputMethodOverride -InputTip "0411:00000411"

# ログオフ
logoff

3. Image Assistant からFleet用のスナップショットを作成する

デスクトップの Image Assistant を起動し、ウィザードに従って設定を進める。

  • ADD APPS
    • 公開するアプリケーションのパス、起動パラメータを設定する
Remote Desktop Client C:\Windows\System32\mstsc.exe
Teraterm C:\Program Files (x86)\teraterm\ttermpro.exe
Chrome C:\Program Files\Google\Chrome\Application\chrome.exe
  • CONFIGURE APPS
    • Template User にスイッチしてアプリケーションのデフォルト設定を実施する
    • 今回は何も実行しない
  • TEST
    • Test User でサインインし、インストールしたアプリが正常起動することを確認する
  • OPTIMIZE
    • [Launch]ボタンをクリックすると登録したアプリが自動起動し最適化が実行される
  • CONFIGURE IMAGE
    • ここで設定した Name がフリート設定時にイメージの選択肢として表示される
Name fumidai_win2019-20210124-001
Always use latest agent version On

[Disconnect and Create Image] ボタンをクリックするとデスクトップから切断され、スナップショットの作成が実行される。

AWS Console: AppStream2.0 ➡ Images ➡ Image Builder

30分程度でイメージのステータスが Snapshotting ➡ Stopped に遷移する。
今後アプリや設定のアップデートの際はこのイメージを更新し、都度 Image Assistant でスナップショットを追加していく。

4. Fleetを作成する

フリートは同じスナップショットからデプロイされた公開サーバ群のこと。
Citrix XenAppでいうマシンカタログに相当する。

AWS Console: AppStream2.0 ➡ Fleets ➡ Create Fleet

  • Fleet Details
Name fumidai_win2019_fleet
  • Choose imaga
    • Private でフィルタして、自身が作成したイメージのスナップショットを選択する
Image fumidai_win2019-20210124-001
  • Configure fleet
    • デプロイする公開サーバのスペック、フリートタイプ(課金タイプ)、セッション設定、キャパシティを設定する
    • 課金タイプが On-Demand の場合、Suspend状態の公開サーバにログオンする際120秒待ち時間が発生する
    • キャパシティ設定 = Auto Scaling設定 で、ユーザ接続数に応じてインスタンスをスケールする
Instance Family General Purpose
Choose instance type 2vCPU, 4GB RAM
Fleet Type details On-demand
Maximum session duration in minutes 960min
Disconnect timeout in minutes 15min
Idle disconnect timeout in minutes 15min
Minimum capacity 1
1以上にすること。0の場合インスタンスが全く起動しなかった。
Maximum capacity 5
Stream view application
デスクトップを公開する場合は Desktop を選択
Scaling Details default
IAM Role 設定しない
  • Configure Network
    • フリートをデプロイするサブネット、アタッチするセキュリティグループを設定する
    • イメージのカスタマイズ時と同様、既存のプライベート・サブネットを指定した
Default Internet Access Off
Subnet 既存のプライベート・サブネット
Security Group default

[Create] ボタンをクリックするとフリートのデプロイが開始される。

AWS Console: AppStream2.0 ➡ Fleets

30分程度でフリートのステータスが Starting ➡ Running に遷移する。

  • フリートタイプ = On-Demand の課金について
    • FleetをStopすると、全インスタンスが削除される。
    • Stopの状態でサービスの利用は出来ない。
    • 次回利用時はマニュアルでStartしてから、利用可能になるまで30分程度かかる。
    • Suspend中のインスタンスにも僅かに課金されるため、長期間使用しないならStopしておいた方がいい。

5. Stackの設定を作成する

公開するフリートとログインポータル設定、ユーザレベル設定のセットをStackと呼ぶ。
Citrix XenAppでいうデリバリーグループに相当。

AWS Console: AppStream2.0 ➡ Stacks ➡ Create Stack

  • Stack Details
    • ログインポータルに表示される名前、先の手順でデプロイしたフリート、アクセス経路を指定する
Name fumidai_for_myvpc
Display name Fumidai for MyVPC
ログインポータルに表示される名前
Fleets fumidai_win2019_fleet
Endpoint Internet
Embed Appstream2.0 何も設定しない
自前のWebサイトにAppStreamの画面を埋め込む時に使うらしい
  • Enable Storage
    • ユーザのログイン時、フリート内の公開サーバはランダム選出される(Floating)
    • Citrix XenApp等ではNASホームフォルダを用意するが、AppStream2.0の場合はS3を使用可能
    • S3バケットは自動的に作成される
    • Google Drive、MS OneDriveの指定も可能
    • ログアウト後もユーザ個別のアプリ設定を保持したい場合は、後述の User Settings で Enable application settings persistence をOnにする
Enable home folders On
  • Use Settings
Clipboard Copy and paste
Copyのみ、Pasteのみ、両方無効が選択可能
File transfer Upload and Download
Uploadのみ、Downloadのみ、両方無効が選択可能
Print to Local device Disabled
Password sign in for Active Directory Enabled
Smart card sign in for Active Directory Disaled
Enable application settings persistence On
Settings group fumidai_for_myvpc
複数のStackで設定置き場を共有したい場合にこのグループ名を指定する

6. ローカルユーザを作成してStackにアサインする

公開サーバログオン時のユーザ認証は、AppStreamのローカルユーザ、自身の所有しているActive DirectorySAMLのいずれかを構成出来る。
クライアントの接続元IPでアクセス制限を実行したい場合は、SAMLのIDプロバイダ側で制御する必要がある。例えばAzure ADの条件付きアクセス。

AppStreamのローカルユーザを使用する。

AWS Console: AppStream2.0 ➡ User Pool ➡ Create User

Emailは実在のメールアドレスを指定すること。
ユーザを作成したら、前のステップで作成したStackにアサインする。

AWS Console: AppStream2.0 ➡ User Pool ➡ ユーザを選択 ➡ Action ➡ Assign stack

アサインしたStack用のログインポータルのURLがユーザのEmailに送信される。
初回ログイン時はパスワードの初期化を要求される。ログイン後、公開アプリケーションのアイコンが表示されていれば成功!

個人でMS Azureの実習を始める手順①

Microsoftアカウントの準備

今回は個人学習用なので、個人のMicrosoftアカウントを使用して始める。企業でOffice365、MS365を契約済みの場合、Azure AD Basicのラインセンスで既に組織アカウントが作成されているはず

  • 適当なMicrosoftアカウントを作成する
    • このドキュメントでは hogexxx@example.com とする

1. 適当なレジストラ独自ドメインを取得する

さくらインターネットの場合、ドメイン取得 + メールボックス = 2,934円/年

何かしらサーバを契約しないとDNSのゾーンファイルを管理できなかったので、一番安いメールボックスを契約した。
このドキュメントでは aabbcc12345.net とする

2. MicrosoftアカウントでAzureを新規契約する

https://azure.microsoft.com/ja-jp/free/ の "Start free" ボタンからウィザードに従って無料アカウントを作成する。

Microsoftアカウントがサブスクリプションの「アカウント管理者」兼「サービス管理者」に設定される。
「アカウント管理者」、「サービス管理者」は従来のサブスクリプション管理者の役割で強力な権限を持つ。割り当ての変更方法は後述する。

以下のサブスクリプションが作成され、下記「規定のディレクトリ」と紐づけされる

サブスクリプション Azureサブスクリプション1(名称は後から変更可)

以下のAzure AD/テナントが作成される

ディレクトリ名 規定のディレクトリ(名称は後から変更可)
ライセンス Azure AD Free
プライマリドメイン hogexxxexample.onmicrosoft.com

Azure ADに以下のユーザが作成される

ユーザープリンシパル hogexxx_example.com#EXT#@hogexxxexample.onmicrosoft.com
Azure ADロール グローバル管理者
ソース Microsoft Account

3. Microsoftアカウントに全Azureリソースへのアクセス権を与える

Azure Portal: 規定のディレクトリ ➡ プロパティ ➡ Azure リソースのアクセス管理

'自分のMicrosoftアカウント' は、このテナント内のすべての Azure サブスクリプションおよび管理グループへのアクセスを管理できます Yes

これを有効にしておかないと、MicrosoftアカウントでAzure MFAの管理画面等にアクセスする際、組織アカウントを要求されて画面遷移出来ない。
別の組織アカウントを管理者として運用するつもりであれば、多分不要な手順。

4. Azure ADにカスタムドメインを追加し、プライマリドメインを変更する

ドメイン名を追加する

Azure Portal: Azure AD ➡ カスタムドメイン名 ➡ カスタムドメインの追加

取得した独自ドメインを入力すると、ゾーンファイルに追加するTXTレコードが表示されるので、1ベンダのゾーン設定画面でレコードを追加する。*1

追加したカスタムドメインをプライマリドメインに変更する

Azure Portal: Azure AD ➡ カスタムドメイン名 ➡ 追加したドメイン名をクリック ➡ ✓プライマリにする

5. Azure ADの管理者用のユーザを追加し「グローバル管理者」のAzure ADロールを割り当て、2要素認証を設定する

Azure Portal: Azure AD ➡ ユーザー ➡ 新しいユーザー

ユーザー名 msazadmin@aabbcc12345.net
名前 mszaadmin
場所 日本
役割(AzureADロール) グローバル管理者

Azure Portal: Azure AD ➡ ユーザー ➡ msazadmin ➡ 認証方法

電話 +81 90xxxxxxxx

作成した組織アカウントでAzureポータルにサインインを試行し、SMSか電話認証を要求されることを確認する。

  • Microsoft Authenticatorのアプリを使用する場合はAzure AD P2ライセンスを購入し、ユーザにアサインする必要がある
  • Azure ADロールの「グローバル管理者」の呼び方(呼び方を統一してほしい。。。)
    • Azure Portal : グローバル管理者
    • Microsoft365管理センター : 全体管理者
    • API : Company Administrator
  • Azure ADロールの「User」について
    • PowershellからAzure AD Roleテンプレートの存在は確認出来るが、Enable出来ないしポータルにも表示されないため、暗黙のロール扱いと思われる
    • Microsoft365からユーザを作成するときのロール選択に、User(no admin center access), Admin center access とあるため、Azure ADのロール無しユーザ=Userロールということっぽい

6. 作成したAzure ADの管理者に「所有者」のAzureロールを割り当てて、サブスクリプションの管理者に設定する

Azure Portal: サブスクリプション ➡ IAM ➡ +追加 ➡ ロールの割り当ての追加

役割(Azureロール) 所有者
アクセスの割当先 ユーザー、グループ、またはサービスプリンシパル
選択 msazadmin@aabbcc12345.net

Azure ADロールと、Azureロールは別ものなので注意。*2

Azure ADロール Azure ADに対するアクセス権
Azureロール サブスクリプション(課金情報)・Azureリソースに対するアクセス権
AWSのIAMロールに相当
Azure初期は「サービス管理者」、「アカウント管理者」、「共同管理者」を使用していたが、現在はロールベースに変わって新規作成出来は出来ない
用途別にビルトインのロールが用意されているが、カスタムロールの作成も可能
「所有者」ロールは従来の「サービス管理者」に相当する

従来のAzureロールの変更方法

従来の管理者ロールはAzureポータルから新規割り当て出来ないが、Azure契約者のアカウントに「サービス管理者」、「アカウント管理者」が割り当てられるため、必要に応じて割り当ての変更を申請する必要がある。

サービス管理者の変更 Azure Portal: サブスクリプション ➡ プロパティ ➡ サービス管理者の変更*3
アカウント管理者の変更 Azure Portal: コストの管理と請求 ➡ サブスクリプション ➡ 課金所有権を譲渡したいサブスクリプションをクリック ➡ 課金所有権の譲渡*4

7. EMS E5の90日評価版ライセンスをアクティブ化する

EMS E5が無いと色々検証出来ないので試用版をアクティブ化する。
EMS E5にはAzure AD P2, Multi-Factor Authentication, Intune, Azure Identity Protection等が含まれる。*5

Azure Portal: Azure AD ➡ ライセンス ➡ 全ての製品 ➡ 試用/購入 ➡ 右ペインから EMS E5 のアクティブ化をクリック

なお、EMSライセンスはMicrosoft365プロダクトなので、後述の通りMicrosoft365管理センターからか、適当な販社からボリュームライセンスの購入が多分正規の方法。

8. Office365 Trialの取得

Microsoft365プロダクト(EMS, Office, etc)のライセンスに対する購入・管理・支払いは、Microsoft365管理センターから実行・設定する。
Azureサブスクリプションと課金先が連携しないので注意。
https://admin.microsoft.com/AdminPortal/ (組織アカウントでアクセス)

トライアルライセンスの取得

Microsoft365管理センター -: 課金情報 ➡サービスを購入する ➡ Office 365 E3(≠月極め) ➡ 詳細 ➡ 無料試用版を入手する

支払方法(クレカ等)の設定 Microsoft365管理センター: 課金情報 ➡ 支払い方法
使用中の製品の詳細 Microsoft365管理センター: 課金情報 ➡ お使いの製品
ライセンス利用状況の詳細 Microsoft365管理センター: 課金情報 ➡ ライセンス

Powershellメモ2

System.Array クラスで配列を作成する

  • 配列の型を指定しないと System.Array クラスで作成される。
  • 要素の追加は += 演算子を使用するが System.Array は固定長配列なので、追加処理の度に配列の再作成が実行されてめっちゃ遅い。

# System.Array クラスで空の配列を作成
> $array = @()
> $array.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

# += 演算子で要素を追加
> $array += 1
> $array += 2..5
> $array
1
2
3
4
5

# 配列を初期化
> $array.Clear()

# 初期値の入った配列を作成
> $array = @('a', 'b', 'c', 'd', 'e')

# Count プロパティで要素数を取得
> $array.Count
5

# インデックスを指定して要素を取得
> $array[2]
c

# インデックスを指定してスライスを取得
> $array[2..4]
c
d
e

# 配列に指定の要素が含まれるか判定
> $array.Contains("c")
True

# 配列をコピー
> $array_clone = $array.Clone()
> $array_clone
a
b
c
d
e

System.Collections.ArrayList クラスでコレクションを作成する

  • コレクションなので可変長の配列として使える
  • System.Array クラスより使えるメソッドが多い
  • 要素の追加は += も使えるが Add() メソッドの方が高速、ループで追加するような場合は後者を使ったほうが良い

# System.Collections.ArrayList クラスで空のコレクションを作成
> $array = New-Object System.Collections.ArrayList

# 以下でも同じ
> [System.Collections.ArrayList]$array = @()

> $array.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ArrayList                                System.Object

# Add() メソッドで要素を追加
> $null = $array.Add('one')
> $null = $array.Add('two')
> $null = $array.Add('three')
> $null = $array.Add('four')
> $null = $array.Add('five')
> $array
one
two
three
four
five

# $array.Add(1..5) は0番目の要素に 1,2,3,4,5 の配列が格納される

# Count プロパティで要素数を取得
> $array.Count
5

# インデックスを指定して要素を取得
> $array[2]
three

# インデックスを指定してスライスを取得
> $array[2..4]
three
four
five

# RemoveAt() メソッドで指定インデックスの要素を削除
> $array.RemoveAt(0)

# Remove() メソッドで一致する要素を削除
> $array.Remove('five')

# Insert() メソッドで指定インデックスに要素を挿入
> $array.Insert(0,'壱')
> $array
壱
two
three
four

# コレクションに指定の要素が含まれるか判定
> $array.Contains('壱')
True

# 昇順でソート
> $array.Sort()
> $array
four
three
two
壱

# 降順でソート
> $array.Reverse()
> $array
壱
two
three
four

# コレクションの複製
$array_clone = $array.Clone()

# コレクションを初期化
> $array.Clear()

Hashtable を Foreach-Object or foreach() したい

  • $hash | Foreach-Object {} して結構ハマる、良く忘れる

> $hash = @{ 'one' = '壱'; 'two' = '弐'; 'three' = '参'; 'four' = '肆'; 'five' = '伍' }
> $hash.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

> $hash

Name                           Value
----                           -----
one                            壱
three                          参
two                            弐
four                           肆
five                           伍


# 以下は想定通り動かない
> $hash | ForEach-Object { Write-Output ($_.Name + " is " + $_.Value) }
 is

# これなら動く
> $hash.Keys | ForEach-Object { Write-Output ($_ + " is " + $hash[$_]) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍

# GetEnumerator() で列挙子を返すと一番しっくりくる
> $hash.GetEnumerator() | ForEach-Object { Write-Output ($_.Name + " is " + $_.Value) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍

# foreach() なら以下のように
> foreach( $key in $hash.Keys ) { Write-Output ($key + " is " + $hash[$key]) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍

# GetEnumerator() を使う場合
> foreach( $obj in $hash.GetEnumerator() ) { Write-Output ($obj.Name + " is " + $obj.Value) }
one is 壱
three is 参
two is 弐
four is 肆
five is 伍