覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

PowerShell - クリップボードの画像データをファイルに保存する

コピーした画像 や コピーしたExcelのセルのデータ などで 画像として保存可能なクリップボード上のデータを保存するためのPowerShellの例です。

Windows 標準の Windows PowerShell (PowerShell 5.x) であれば以下のようなコマンドで
クリップボードのデータを画像として保存できます。

(Get-Clipboard -Format Image).Save("Image-file.png")


が、PowerShell Core(PowerShell 7.x)では、このコマンドはエラーになります(対応していません)


ですので、以下のようなやり方(Windows.Forms.Clipboard)を使います。

この PowerShell は、クリップボードのデータをデスクトップに ImageFile.png という名前で保存する例です。

<# 
コピーしたデータ(クリップボードのデータ)を画像としてデスクトップに保存します。
保存時のファイル名は $SaveImgeFile に定義しています
#>

Add-Type -AssemblyName System.Windows.Forms

# 保存用ファイル名
$SaveImgeFile = 'ImageFile.png'

$DesktopPath = [System.Environment]::GetFolderPath("Desktop")

$clip = [Windows.Forms.Clipboard]::GetImage()

if ($null -ne $clip) { $clip.Save($DesktopPath + '\' + $SaveImgeFile) }


以下のPowerShellは単純にファイル名の頭に現在日時情報を付与した例です。その他は上記の例と変わりません。

<# 
コピーしたデータ(クリップボードのデータ)を画像としてデスクトップに保存します。
保存時のファイル名のSuffixは $SaveImgeFile に定義しています
#>

Add-Type -AssemblyName System.Windows.Forms

# 保存用ファイル名
$SaveImgeFile = 'ImageFile.png'

$SaveFileNamePrefix = Get-Date -Format "yyyyMMdd-HHmmssfff"

$DesktopPath = [System.Environment]::GetFolderPath("Desktop")

$clip = [Windows.Forms.Clipboard]::GetImage()

if ($null -ne $clip) { $clip.Save($DesktopPath + '\' + $SaveFileNamePrefix + '_' + $SaveImgeFile) }


というわけで、クリップボードに画像として保存可能なデータがある状態で、上記のPowerShellを実行すれば画像として保存されます。

Azure SQL Database - SSHポートフォワーディングでのSSMSの設定

Azure SQL Database のDB に SQL Server Management Studio (SSMS) で手元のPC環境から接続したい、
だけど、会社のファイアウォールによって 1433 ポート(SQL Server接続用ポート)での通信が許可されていない。
だから、SSHポートフォワーディング(SSHトンネリング)で 踏み台用サーバ(JumpBox Server)経由で Azure SQL Database と通信する。
というケースは、まーまーあるんだと思います。

で、試しにやってみたら SSMS の接続設定の方法が結構よくわからず意味もなくハマってしまったので、今後のためにメモしました。


前提条件

今回試した環境等の条件です。条件が違っているとうまく行かない可能性もあります。

  • Azure SQL Database の ファイアウォール設定
    • パブリック ネットワーク アクセスの拒否 : いいえ
    • 接続ポリシー : 規定
    • 踏み台サーバのIPアドレスからの接続は許可されている必要があります。
  • 踏み台サーバ(JumpBox Server)
    • Azureの外に配備
      • Azureの中にSSH接続する踏み台サーバを用意すると、今回のやり方ではうまくいかないかもしれません。(ポート 1433 以外も絡んで来る可能性があるため)
  • SSMS
    • 18.8 を使用

本エントリではSSHポートフォワーディングはできている状態を想定しています。
今回の例では、ローカル の 11433 ポートへの通信が結果的に Azure SQL Databaseの1433ポートへの通信となる状況にしています。

ポートフォワーディング等については以下のエントリを参照してください。


SSMSの設定

SSMSの接続設定に関してタブごとに以下のようにします。

ログイン

  • サーバの種類:
    • データベースエンジン
  • サーバ名:
    • 127.0.0.1,11433
      • IPアドレス と ポート番号 の間は : (コロン) ではなく , (カンマ)
      • 11433 のポート番号は、実際のポートフォワーディングの設定に合わせて値を変更してください
    • 認証:
      • SQL Server 認証
      • ログイン: <ユーザ名>@<DBサーバのサーバ名>
        • 例:dbuser@dev-dbserver-01.database.windows.net
      • パスワード:<DB接続用パスワード>

<DBサーバのサーバ名> は、Azure portal で対象の SQL Database の概要に、「サーバー名」として表示されている値です。

f:id:nini_y:20210424235108p:plain


接続プロパティ

  • データベースへの接続:<接続するDB名>
    • 例:Dev-DB-01
  • 暗号化接続:チェックON
  • サーバー証明書を信頼する:チェックON


Always Encrypted

デフォルトのまま


追加の接続パラメーター

デフォルトのまま(空白)


SSMSの接続の設定画面 例

実際に設定をしたSSMSのサーバへの接続ウィンドウの状況は以下のとおりです。

f:id:nini_y:20210425000153p:plain

f:id:nini_y:20210425000407p:plain

f:id:nini_y:20210425000416p:plain

f:id:nini_y:20210425000426p:plain


まとめ

ここに記載した設定をした状態でSSMSで「接続」を行えば、Azure SQL Database へのDBに接続できます。



関連サイト

Azure SQL Databse と SQL Server のバージョン

以下、ほぼメモです。

Azure SQL Databseは、Azureで提供されているフルマネージドの PaaSデータベース エンジンで、
最新の安定したバージョンの SQL Server データベースエンジンおよびパッチが適用された OS 上で実行されているものです。


で、例えば 2021年4月時点でAzure SQL Server上のDBに接続して、

SELECT @@VERSION

という内部のバージョンを確認するSQL (T-SQL) を実行すると以下の結果が返ってきました。

Microsoft SQL Azure (RTM) - 12.0.2000.8
Feb 20 2021 17:51:58
Copyright (C) 2019 Microsoft Corporation


12.0.2000.8 という値だけに着目すると SQL Server 2014 の エンジンのバージョンの 12.0.2000.8 と一致しているので、
SQL Server 2014 が動作してるということなのかな。とか一瞬思ったのですが、
それは大いなる勘違いで
Azure SQL DatabseSQL Server のエンジンのバージョンは異なっているとのことです。


上記ページの前半の重要に以下のように書かれています。

SQL Server と Azure SQL Database のデータベース エンジンのバージョン番号は類似のものではありません。
別個の製品に与えられる内部製造番号になっています。 
Azure SQL Database のデータベース エンジンは SQL Server データベース エンジンと同じコードに基づいています。
最も重要なことですが、Azure SQL Database のデータベース エンジンには常に最新の SQL データベース エンジン ビットが与えられます。
Azure SQL Database のバージョン 12 は SQL Server のバージョン 15 より新しくなります。


というわけで、Azure SQL Database が返してきた 12.x というエンジンのバージョンは、
SQL Server のエンジンバージョン15.x と同等(か、それ以上)という感じで、結果的に SQL Server 2019 と同等ということになるようです。

Azure SQL Databseのサービスの定義通り、最新バージョンの SQL Server が動作してるようです。

Windows 10 - バージョン情報の確認・取得方法

Windows 10 を使っていて、一概に Windows 10 といっても定期的に大きなバージョンアップが行われていて、
そのバージョン次第でサポート切れみたいのこともあります。

今までの Windows に比べても今、このPC バージョンいくつ何だっけ? という確認をしなければならない場面が多い気がします。


視覚的に確認

複数確認できる場所(手順)がありますが、とにかく以下の手順が一番手っ取り早いです。

1) Windowsキー + R キーを押して、ファイル名を指定して実行のウィンドウを表示

2) winver と入力してOK

f:id:nini_y:20210423094633p:plain

3) Windows のバージョン情報が表示されます

f:id:nini_y:20210423094700p:plain

上記の赤枠の部分です。バージョンは、20H220H2 (OS Build 19042.928))ということになります。


PowerShell で 取得

ウィンドウ等で視覚的に確認でもよいんですが、文字情報(文字列)としてバージョンを取得したい場合もあるかもしれません。PowerShellを使いましょう。

20H2 よりも前か、 20H2 (以降) か でやり方がちょっと異なります。

Windows 10 20H2 よりも前

以下のいずれかのコマンドで取得できます。後者のコマンドだとちょっと時間がかかります。

$CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
"Version " + $CurrentVersion.ReleaseId + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"
$ComputerInfo = Get-ComputerInfo
"Version " + $ComputerInfo.WindowsVersion + " (OS Build " + $ComputerInfo.OsBuildNumber + "." + $ComputerInfo.WindowsUBR + ")"


実行例

PS C:\Users> $CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
PS C:\Users> "Version " + $CurrentVersion.ReleaseId + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"
Version 2004 (OS Build 19041.572)

Version 2004 (OS Build 19041.572) というバージョン情報が取得できています。


Windows 10 20H2

Windows 10 20H2 (以降) でも上記のコマンドでバージョン情報は取得できます。

Windows10 20H2 の PC で実行すると以下のようになります。

PS C:\Users> $CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
PS C:\Users> "Version " + $CurrentVersion.ReleaseId + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"
Version 2009 (OS Build 19042.928)

Version 2009 (OS Build 19042.928) というバージョン情報が取得できています。

2009 というのは内部的なバージョンで間違った値ではないんですが、
Windows 10 の バージョンの表記が分かりにくいとかいう色々なことがあったらしく、
内部的にはこれまでと同じルールの 2009 という値を持ってますが、 バージョンのラベルとして 20H2 という表記になったようです。


では、202H という値はどこから取ればいいのかというと、
レジストリの \HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersionDisplayVersion に保持されているので、そこから取得します。

f:id:nini_y:20210423101259p:plain


先のPowerShellのコマンド で $CurrentVersion.ReleaseId としていた部分を $CurrentVersion.DisplayVersion に変更すればよいことになります。

というわけで実行するコマンドとしては以下になります。

$CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
"Version " + $CurrentVersion.DisplayVersion + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"


ワンライナーにするなら以下(セミコロンで区切っているだけ)

$CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"; "Version " + $CurrentVersion.DisplayVersion + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"


実行例

PS C:\Users> $CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"; "Version " + $CurrentVersion.DisplayVersion + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"
Version 20H2 (OS Build 19042.928)


無事に Version 20H2 (OS Build 19042.928) という値を取得できました。


両方まとめると

Windows 10 20H2 よりも前と 20H2以降 の環境をまとめて扱うなら、
上記に書いてきた内容をひとまとめにして以下のようなコマンドで値を取得できます。

$CurrentVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" 
if ($CurrentVersion.DisplayVersion -ne $null) { $DispVersion = $CurrentVersion.DisplayVersion } else { $DispVersion = $CurrentVersion.ReleaseId }
"Version " + $DispVersion + " (OS Build " + $CurrentVersion.CurrentBuild + "." + $CurrentVersion.UBR + ")"

Windows - curlコマンド

Windows 10 は、標準でcurlコマンドが使えるようになってたんですね。(知らなかったです)

Windows標準のcurlについて、少しだけ確認してみました。


Wndows PowerShell 5.1

デフォルトでインストールされている Wndows PowerShell 5.1 環境で curl と実行してみたら以下のようになりました

PS C:\Users> curl

コマンド パイプライン位置 1 のコマンドレット Invoke-WebRequest
次のパラメーターに値を指定してください:
Uri:

何か思ってたのと違うので、よくよく確認してみたら
curl というコマンドは Invoke-WebRequest の Alias になってました。(以下の通り)

PS C:\Users> Get-Command curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest


PS C:\Users> Get-Command Invoke-WebRequest

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Invoke-WebRequest                                  3.1.0.0    Microsoft.PowerShell.Utility


ただし、実際には上記の curl とは関係なく、 curl.exe というものが標準でインストールされています。
curl.exe とやれば実行できます。(こっちのほうが想定してた curlコマンドに近いと思われます)

PS C:\Users> curl.exe
curl: try 'curl --help' for more information
PS C:\Users> Get-Command curl.exe

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     curl.exe                                           7.55.1.0   C:\WINDOWS\system32\curl.exe


PowerShell 7.1

標準の Windows PowerShell とは別で PowerShell 7.1 もインストールしているので、
そちらでも curlコマンドを確認してみました。今回確認した環境の情報(バージョン等)は以下の通りです。

PS C:\Users> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.3
PSEdition                      Core
GitCommitId                    7.1.3
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0


curlについて確認した結果は以下の通りです。

PS C:\Users> curl
curl: try 'curl --help' for more information
PS C:\Users> Get-Command curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     curl.exe                                           7.55.1.0   C:\WINDOWS\system32\curl.exe

こっちは最初から curlcurl.exe を指してます。(もしかしたら環境にもよるかもしれませんが)


ついでに curl --version も実行してみました。

PS C:\Users> curl --version
curl 7.55.1 (Windows) libcurl/7.55.1 WinSSL
Release-Date: 2017-11-14, security patched: 2019-11-05
Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL


話は、それますが DOSプロンプトでも curlcurl.exeC:\WINDOWS\system32\curl.exe) を指しています。


WSL

WSL (Ubuntu 20.04.2 LTS) での curl もついでに確認。

user01@PC-001:/mnt/c/Users$ curl
curl: try 'curl --help' or 'curl --manual' for more information
user01@PC-001:/mnt/c/Users$ which curl
/usr/bin/curl
user01@PC-001:/mnt/c/Users$ curl --version
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

Windows版標準のcurl.exeとは バージョン、扱えるプロトコル、機能 に差異があるようです。


まとめ・補足

  • curl と安易に実行しても、実行環境によって curl.exeだったり、そうでなかったりしています。
  • curl.exe は Windows用にビルドされた curl のためか、Linux上のcurlとは扱えるプロトコルやパラメータに差異があります。
  • (実行例が無いので分かりにくいですが) curl.exeでも、Linux用にビルドされているcurlとほぼ同じ操作ができます。


HTTPステータスコードだけ取得

以前書いたこのエントリをWindows標準のcurl.exeで実現する場合は以下のようになります。

curl -s {リクエスト先のURL} -o nul -w '%{http_code}\n'

上記は PowerShell 7.1 で実行する想定です。