conf t

インフラエンジニアのメモ

Windowsでpowershellを使用しランダムなパスワードを生成する

f:id:monaski:20150929175237j:plain

linuxではmkpasswdや/dev/urandomを加工すればランダムパスワードが生成できますが、
Windowsでは簡単な方法がなかなかありません。

今回たったの2ステップで、しかもフリーソフトのインストールはせずに
デフォルトのWindows環境でパスワードを生成する方法を考えましたので共有します。

目次

パスワード生成手順

1.powershellを起動

powershellを起動します。
Windowsキー + Rを押して「ファイル名を指定して実行」を表示し、
powershell」と入力し、Enterを押します。
f:id:monaski:20150929175230j:plain

2.以下コマンドを貼り付け実行

表示されたpowershellプロンプトに以下コマンドを貼り付け、Enterを押し実行します。
これでパスワードが生成され、プロンプトに表示されます。

Add-type -AssemblyName System.Web;[System.Web.Security.Membership]::GeneratePassword(10,3)

実行結果

PS C:\Users\test> Add-type -AssemblyName System.Web;[System.Web.Security.Membership]::GeneratePassword(10,3)
z1N%3+]JlD ←これが生成されたランダムパスワードです。
PS C:\Users\test>

f:id:monaski:20150929175237j:plain

解説

Add-type -AssemblyName System.Web

powershellに.NetのアセンブリSystem.Webを読み込ませています。
powershellはあらかじめいくつかの.netアセンブリを読み込みますが、
他のアセンブリを読み込みたい場合はAdd-typeを使います。

[System.Web.Security.Membership]::GeneratePassword(10,3)

GeneratePasswordでパスワードを生成します。
10はパスワードの長さ、3はパスワードに最低限含まれる記号の数を指定しています。
先に前述のアセンブリを読み込んでおかないと、実行できません。

なお、一度最初のコマンドでアセンブリを読み込ませたら、
プロンプトを閉じるまでは有効なので、 以後は2番目のGeneratePasswordを実行するだけでパスワードは生成できます。

応用編:使用する文字を制限

記号なし、英数字のみ

アルファベット大文字小文字と数字のみの8文字のパスワードを生成します。
以下ではGeneratePasswordで10文字のパスワードが生成され、そのうち2文字が記号ですが、この記号2文字を取り除くことで8文字の記号なしのパスワードを生成しています。
powershellは大文字と小文字を区別しないため、[a-z]で大文字もヒットします。 区別したい場合は、-replaceの代わりに-creplaceを使います。

Add-type -AssemblyName System.Web;[System.Web.Security.Membership]::GeneratePassword(10,2) | %{$_ -replace "[^a-z0-9]",""

数字のみ

128文字のパスワードから数字以外を削除後、長さをカットして8文字のパスワードを生成しています。
元々のGeneratePasswordで生成されるパスワードに含まれる数字が少ないと、8文字分切り取れず作成に失敗します。
そのため、最初に作成するパスワードの長さを関数で指定可能な最大値(128)を指定し、なるべく失敗しないようにしています。

$c=[System.Web.Security.Membership]::GeneratePassword(128,0) | %{$_ -replace "[^0-9]",""};$c.SubString(0,8)

乱数を生成するGet-Randomでも生成できます。
以下では8文字の数字パスワードを作成しています。
生成されるのは整数であるため、そのままだと先頭0のパスワードが生成できません。
9桁の数を生成してから、先頭行を削除して8桁のパスワードを生成しています。

$c=Get-Random -minimum 100000000 -maximum 999999999;([String]$c).SubString(1,8)

簡単に実行できるようにする

今回ご紹介したパスワード生成コマンド、ワンライナーとはいえコマンドが結構長いので覚えておくのは厳しいです。
そこで、powershell起動時に関数を作成し、それを使うようにすることで負担を減らします。
powershellにはプロファイルというファイルがあり、
ここにコマンドを書いておくと、起動時に毎回実行されます。
このプロファイルに、パスワード生成関数を記述しておきます。

以下コマンドでプロファイルを新規に作成後メモ帳で開きます。

New-item –type file –force $profile
notepad $profile

メモ帳が開くので、以下を貼り付けて保存する。

Add-type -AssemblyName System.Web

function Generate-Password([int]$a, [int]$b) {

    [System.Web.Security.Membership]::GeneratePassword($a,$b)

}

これで、長いコマンドを毎回入力しなくとも、以下コマンドで
この記事で最初に紹介したコマンドと同等にパスワードが生成できるようになりました。
以下コマンドは10文字パスワードで、最低3文字が記号のパスワードを生成しています。
Geneあたりまでタイプして、タブを押せばコマンドが補完されますので、覚える量はかなり少なくて済みます。

PS C:\Users\test> Generate-Password 10 3
Ov9gp]@[zq

ちなみにこの記事を書く際、はてなブログpowershellシンタックスハイライトする際指定する文字がわからなかったので、
知ってたら教えていただけると嬉しいです。

10/1追加

パワーシェルコンソールはコピー操作が面倒なため(Windows10なら別かもですが)   簡単にコピペができるようにGenerate-Password関数を改良しました。
生成したパスワードを、自動でクリップボードにコピーしてくれるようにしました。
これで、わざわざパスワードを選択してコピーしなくても、そのままCtrl + Vすれば生成したパスワードを 貼り付けられます。

Add-type -AssemblyName System.Web

function Generate-Password([int]$a, [int]$b) {

    $pass = [System.Web.Security.Membership]::GeneratePassword($a,$b)
        $pass | clip
        $pass

}

10/21 追記

powershellは実行速度に難があるため、C#で作成し直した。
monaski.hatenablog.com

参考:

パスワードのようなランダムな文字列を生成する - .NET Tips (VB.NET,C#...)

https://msdn.microsoft.com/ja-jp/library/system.web.security.membership.generatepassword(v=vs.110).aspx