たれながし.info

とあるITエンジニアの備忘録

PowerShellで文字列がIPアドレス(IPv4)か判定する方法

PowerShellで文字列がIPアドレスIPv4)か判定する方法です。

正規表現を使う方法

^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$



ということで、下記でIPv4アドレスか判断できる

> $str -match "^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"



いくつかの文字列でテストしてみる。

# テストスクリプト
$list = @(
    '192.168.0.24'
    '10.0.0'
    '256.1.0.3'
    '211.255.1.3'
)

$regex = "^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$"

foreach($ip in $list){
    $bool = $ip -match $regex
    Write-Host "${ip}: ${bool}"
}

# 結果
192.168.0.24: True
10.0.0: False
256.1.0.3: False
211.255.1.3: True

その他の方法

型変換を使って判定することもできるらしい。
mtgpowershell.blogspot.com

AzureADのネストグループの全所属メンバーをPowerShellで出力する

目的

AzureADの特定グループの全所属メンバーをPowershellで出力しようとしたところ、グループがネストされている場合にうまく出力できませんでした。
解決策を調べたところ、関数を作成して解決している人がいたので試してみます。


<参考にしたサイト>
www.fixes.pub

事前準備

PowerShellでAzureADを操作するにはモジュールが必要なのでインストールする
PowerShellは管理者権限で起動する必要がある

Install-Module -Name AzureAD



AzureADに接続し認証する
※「Code: Authentication_Unauthorized」と表示される場合はTenantIdでディレクトリを指定する

Connect-AzureAD -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

問題点

下記のようなネストされたグループを考えます。

Group_A
├─UserA
└─Group_B
    ├─UserB
    └─UserC



「Get-AzureADGroupMember」でグループAのメンバーを取得してもObjectIdが取得できるだけで、グループBのメンバーは展開されません

# スクリプト
$groupName = "Group_A"
$groupId = (Get-AzureADGroup -Filter "DisplayName eq '$groupName'").objectId
Get-AzureADGroupMember -objectId $groupId -All $true
# 実行結果
ObjectId                             DisplayName UserPrincipalName                           UserType
--------                             ----------- -----------------                           --------
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx UserA       UserA@xxxxx.onmicrosoft.com Member

DeletionTimestamp            :
ObjectId                     : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ObjectType                   : Group
Description                  :
DirSyncEnabled               :
DisplayName                  : Group_B
...

解決方法

ネストグループを展開する関数を作成することで、全メンバーが出力できます。
※DisplayNameの部分は任意のプロパティに変更しても良い 例)ObjectIdなど

# スクリプト
Function  Get-AzureADGroupMembers($groupId) {
   $output= @()
   $group= (Get-AzureADGroupMember -ObjectId $groupId -All $True| Select ObjectId).ObjectId
   foreach($objectid in $group)
     {
        $aad_object=  Get-AzureADObjectByObjectId -ObjectId $objectid
        #Add to output if object is a user
        if ($aad_object.ObjectType -eq 'User')
        {
                   $output += New-Object PSObject -property @{
                    DisplayName= $aad_object.DisplayName
                 }
        }
        #Recursive call if the object is a group
        if ($aad_object.ObjectType -eq 'Group')
        {
                   $output += Get-AzureADGroupMembers -groupId $aad_object.ObjectId
        }
     }
    return $output
}

$groupName = "Group_A"
$groupId = (Get-AzureADGroup -Filter "DisplayName eq '$groupName'").objectId
Get-AzureADGroupMembers($groupId)
# 実行結果
DisplayName
-----------
UserA
UserB
UserC

おわりに

同様のスクリプトを作成している人が他にもいました。こちらのスクリプトはDeviceも考慮しているようです。
bwit.blog

Azure Blob StorageにPowerShellでファイルアップロード

Azure Blob StorageにPowerShellInvoke-RestMethodでファイルアップロードしてみる。

f:id:tarenagashi_info:20210809132401p:plain:w650

はじめに

Windows10のOS標準機能でAzure Blob Storageにファイルをアップロードしたいと思い検討したところ、PowerShellの「Invoke-RestMethod」でできそうなのでやってみる。
ググったらすでに実施している人がいたので、それを参考にします。

<参考にしたサイト>
rzander.azurewebsites.net

Azure Blob Storageの設定

ストレージアカウント、コンテナの作成

Azure Storageの利用に必要なストレージアカウント、Blobの置き場所となるコンテナを作成する
f:id:tarenagashi_info:20210809132006p:plain:w600

SASの設定

認証のため、SASを設定する。生成されるSASトークンが必要
f:id:tarenagashi_info:20210809132018p:plain:w600

動作確認

Invoke-RestMethodでファイルアップロード

下記PowerShellを実行します。

# Our source File:
$file = "C:\test.txt"

# Get the File-Name without path
$name = (Get-Item $file).Name

# The target URL with SAS Token
$url = "https://testtest20210809.blob.core.windows.net"
$container = "container"
$SAS = "?sv=2020-08-04&ss=b&srt=o&sp=rwdlactfx&se=2021-08-09T12:02:17Z&st=2021-08-09T04:02:17Z&spr=https&sig=4JBC3Aqx1B32eWzBAPx4O0pVOFOXN9%2FSRGk4NPOKBTAg%3D"
$uri = "${url}/${container}/${name}${SAS}"

# Define required Headers
$headers = @{
    'x-ms-blob-type' = 'BlockBlob'
}

# Upload File...
Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -InFile $file

URIのフォーマットは下記となります。

{URL}/{Container}/[Folder Structure/]{FileName}?{SAS Token}

アップロードの確認

無事アップロードされました。
f:id:tarenagashi_info:20210809132031p:plain:w600

ビットコインの発行上限と上限に達する日付を計算してみる

ビットコインの発行上限と上限に達する日付をPythonで計算してみます。

f:id:tarenagashi_info:20210808232522p:plain:h300

はじめに

最近ビットコインについて学んでいて、発行上限があることを知ったので計算してみます。

ビットコインの発行上限について

  • ビットコインには発行上限がある
  • 2009年、最初のマイニング報酬は1ブロックで50BTCだった
  • 210,000ブロック採掘されるとマイニング報酬は半分になる
  • 1ブロックは平均10分でマイニングされるので、約4年 = 約2,100,000分でマイニング報酬は半分になる
  • マイニング報酬が1satoshi(1億分の1BTC=1satoshi)未満になるとビットコインの新規発行が終了する
  • ビットコインの新規発行が終了してもビットコインが終了するわけではない

発行上限の計算

プログラム

Pythonでマイニング報酬が半分になる日付(半減期を迎える日)と発行上限を計算します。

import datetime

income = 50 # 最初のマイニング報酬
halflife = 210000 # 半減期
sum = 0 # 発行総数
dt = datetime.date(2009, 1, 3) #最初のブロック(ジェネシスブロック)が生成された日

while (income > 10**-8):
    print("{}\t発行総数={}".format(dt, sum))
    sum = sum + income * halflife
    dt = dt + datetime.timedelta(days=halflife/(6*24))
    income = income / 2

print("{}\t発送総数={}".format(dt, sum))

実行結果

2009-01-03      発行総数=0
2012-12-31      発行総数=10500000
2016-12-28      発行総数=15750000.0
2020-12-25      発行総数=18375000.0
2024-12-22      発行総数=19687500.0
2028-12-19      発行総数=20343750.0
2032-12-16      発行総数=20671875.0
2036-12-13      発行総数=20835937.5
2040-12-10      発行総数=20917968.75
2044-12-07      発行総数=20958984.375
2048-12-04      発行総数=20979492.1875
2052-12-01      発行総数=20989746.09375
2056-11-28      発行総数=20994873.046875
2060-11-25      発行総数=20997436.5234375
2064-11-22      発行総数=20998718.26171875
2068-11-19      発行総数=20999359.130859375
2072-11-16      発行総数=20999679.565429688
2076-11-13      発行総数=20999839.782714844
2080-11-10      発行総数=20999919.891357422
2084-11-07      発行総数=20999959.94567871
2088-11-04      発行総数=20999979.972839355
2092-11-01      発行総数=20999989.986419678
2096-10-29      発行総数=20999994.99320984
2100-10-27      発行総数=20999997.49660492
2104-10-24      発行総数=20999998.74830246
2108-10-21      発行総数=20999999.37415123
2112-10-18      発行総数=20999999.687075615
2116-10-15      発行総数=20999999.843537807
2120-10-12      発行総数=20999999.921768904
2124-10-09      発行総数=20999999.960884452
2128-10-06      発行総数=20999999.980442226
2132-10-03      発行総数=20999999.990221113
2136-09-30      発行総数=20999999.995110556
2140-09-27      発送総数=20999999.99755528

結果をグラフ化してみました。

f:id:tarenagashi_info:20210808232522p:plain

考察

発行上限について

プログラムによる計算結果では、2140年9月27日に上限「20,999,999.99755528 BTC」を迎える結果となりました。
多くの書籍で、2140年に発行上限を迎えると書いてあるので、概ね合っていそうです。
ちなみに、実際の発行上限は「20999999.9769 BTC」らしいです。下記URLに書いてありました(浮動小数点の制度の問題で、0.9769を2進数で表すのは難しいのでしょう)。

cryptoitalia.org

半減期について

ビットコインはこれまで3回半減期(マイニング報酬の半減)を迎えていて、プログラム計算結果と実際の日付は以下通りとなります。
実際の日付の方がプログラムによる計算結果より早いので、実際の1ブロックの平均マイニング時間は10分より短いのでしょう。

半減期 プログラム計算結果 実際の日付 日付の差
1回目 2012-12-31 2012-11-28 33日
2回目 2016-12-28 2016-07-09 172日
3回目 2020-12-25 2020-05-11 228日

ちなみに…
半減期を3回迎えているということは、全ビットコインの87.5%以上は既に発行済み(誰かの所有物)ということになります。そして、2036年頃には全量の約99%は発行完了となります。

f:id:tarenagashi_info:20210807191855p:plain:h300

Microsoftの月例セキュリティ更新プログラムのリリース日時について

Microsoftの月例セキュリティ更新プログラムのリリース日時について

Microsoftの月例セキュリティ更新プログラムは「米国太平洋標準時の毎月第2火曜日の午前10時」にリリースされる。
全世界で同じタイミングらしい。

<参考>
blogs.windows.com

日本時間ではいつなのか?

米国太平洋標準時は「UTC-8」、日本標準時は「UTC+9」なので、日本時間では「第2水曜日もしくは第3水曜日の午前2時もしくは午前3時」となる。

日本時間で第2水曜日となるのか、第3水曜日となるのかはその月によって異なります。
日本時間で午前2時となるのか、午前3時となるのかはアメリカがサマータイムなのかによります。

サマータイムについて
アメリカでは現地時間の「3月第2日曜日午前2時〜11月第1日曜日午前2時」がサマータイムとなり、1時間早まる。

リリース日時を計算してみる

2023年のリリース日時を計算してみる。

プログラム

import datetime, calendar, pytz

def get_day_of_nth_dow(year, month, nth=2, dow=1):

    first_dow, n = calendar.monthrange(year, month)
    day = 7 * (nth - 1) + (dow - first_dow) % 7 + 1
    
    return day

if __name__ == '__main__':

    year=2023 # 2023年

    print('-' * 49)
    title = '|' + ' ' * 4 + '太平洋時間(PST)' + ' ' * 4 + \
            '|' + ' ' * 5 + '日本時間(JST)' + ' ' * 5 + '|'     
    print(title)
    print('-' * 49)

    for month in range(1, 13):

        # 第2火曜日の日付の取得
        day = get_day_of_nth_dow(year, month)
        naive_pst = datetime.datetime(year, month, day, 10)

        # 太平洋標準時(PST)の計算
        pst = pytz.timezone('US/Pacific')
        aware_pst = pst.localize(naive_pst)

        # 日本標準時(JST)の計算
        jst = pytz.timezone('Asia/Tokyo')
        aware_jst = aware_pst.astimezone(jst)

        print("| {} | {} |".format(aware_pst.strftime("%Y/%m/%d(%a) %H:%M"), aware_jst.strftime("%Y/%m/%d(%a) %H:%M")))
 
    print('-' * 49)

結果

-------------------------------------------------
|    太平洋時間(PST)    |     日本時間(JST)     |
-------------------------------------------------
| 2023/01/10(Tue) 10:00 | 2023/01/11(Wed) 03:00 |
| 2023/02/14(Tue) 10:00 | 2023/02/15(Wed) 03:00 |
| 2023/03/14(Tue) 10:00 | 2023/03/15(Wed) 02:00 |
| 2023/04/11(Tue) 10:00 | 2023/04/12(Wed) 02:00 |
| 2023/05/09(Tue) 10:00 | 2023/05/10(Wed) 02:00 |
| 2023/06/13(Tue) 10:00 | 2023/06/14(Wed) 02:00 |
| 2023/07/11(Tue) 10:00 | 2023/07/12(Wed) 02:00 |
| 2023/08/08(Tue) 10:00 | 2023/08/09(Wed) 02:00 |
| 2023/09/12(Tue) 10:00 | 2023/09/13(Wed) 02:00 |
| 2023/10/10(Tue) 10:00 | 2023/10/11(Wed) 02:00 |
| 2023/11/14(Tue) 10:00 | 2023/11/15(Wed) 03:00 |
| 2023/12/12(Tue) 10:00 | 2023/12/13(Wed) 03:00 |
-------------------------------------------------

「scrcpy」でAndroid端末の画面をUbuntuにミラーリングして操作する

f:id:tarenagashi_info:20210805025409p:plain:h450

はじめに

「scrcpy」というアプリで、Android端末の画面をWindows/MacOS/Linuxミラーリングして操作できます。
ということで、Android端末の画面をUbuntuミラーリングして操作してみる。

<scrcpyのGithub
github.com


ちなみに…
「scrcpy」に音声転送機能は無いので、音声転送をする場合は別のアプリ「sndcpy」を使用する。
※こだわりが無いなら、ライン入力で物理的に繋ぐという方法もある

<sndcpyのGithub
github.com

ミラーリングの実施

環境

Android端末の画面をUbuntuミラーリングする。UbuntuVirtualbox上に仮想マシンとして構築した。

  • 仮想環境:VirtualBox6.1.18
  • ゲストOS: Ubuntu 21.04
  • Android端末:SH-M07(Android10)

Android端末の設定

Android端末の[USBデバッグ]を有効にします。

  • [設定] > [デバイス情報]から[ビルド番号]を7回タップして[開発者オプションを]有効にする
  • [設定] > [システム] > [開発者向けオプション]から[USBデバッグ]を有効にする

Ubuntuの準備

Ubuntuに「scrcpy」をインストールします。

sudo apt install scrcpy

Android端末の接続とミラーリング

Android端末とUbuntuをUSB接続してミラーリングを実行します。

scrcpy

f:id:tarenagashi_info:20210805025409p:plain:h450

sshサーバに接続できない「Could not load host key」「No supported key exchange algorithms」

とあるUbuntuLinuxディストリビューションsshサーバを起動したところ
sshサーバは問題なく起動するのにクライアントが接続できなかった件の対応まとめ。

エラー内容

Ubuntu系では、sshサーバのログは「/var/log/auth.log」に記録されるので確認する。
「Could not load host key」「No supported key exchange algorithms」というエラーが出ていた。

$ tail -f /var/log/auth.log

Jul 17 06:35:45 Tsurugi sshd[13940]: error: Could not load host key: /etc/ssh/ssh_host_rsa_key
Jul 17 06:35:45 Tsurugi sshd[13940]: error: Could not load host key: /etc/ssh/ssh_host_dsa_key
Jul 17 06:35:45 Tsurugi sshd[13940]: error: Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Jul 17 06:35:45 Tsurugi sshd[13940]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key
Jul 17 06:35:45 Tsurugi sshd[13940]: fatal: No supported key exchange algorithms [preauth]

原因

コンフィグで指定しているサーバ側の鍵が1つも存在していませんでした。
(1つでもサーバ側の鍵が存在していれば、接続できない状況は発生していなかったと思われる。)

$ cat /etc/ssh/sshd_config
...
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

対応

セキュリティ的にはdsa/ecdsaは使わない方が良いらしいので、コンフィグからコメントアウトする。
サーバ側の鍵をパスフレーズなしで作成し、sshサーバをリスタートする。

$ sudo vi /etc/ssh/sshd_config
...
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
# HostKey /etc/ssh/ssh_host_dsa_key
# HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

$ sudo ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
$ sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key

$ sudo systemctl restart ssh