or1ko's diary

日々を書きます

ファイアウォールの送信の規則をすべて無効化する方法

管理者でPowerShellのコンソールを起動し、下記を実行する。
ファイアウォール設定は、エクスポートしておいてからやる。

Get-NetFirewallRule -Direction Outbound | ? { $_.Enabled -eq $True } | % { Set-NetFirewallRule -Enabled False -Name $_.Name }

一つの規則を無効化するのにそこそこ時間がかかるため、
有効な規則のみでフィルタしている。

別途、ファイアウォールの送信規則の規定をブロックにすることで、
自端末からのすべての通信をブロックすることができると思われる。

ブラウザがどのポートを使うかしらべたくて試した。
TCP 443とUDP53を許可すればyoutubegoogleなどは利用できたが、
この記事を書こうと試したら、TCP 80の追加も必要だった。
UDP53は、名前解決に利用しているのだろうから、IPアドレスでのアクセスなら不要だと思われる。

クラス名とメソッド名を出力するカスタムDoclet

クラス名やそのメソッド一覧が取得したくてJavadocのカスタムDocletを思い出して、使ってみたが、以外と目的にたどり着けなかったため、記録を残す。

JDK 9 からカスタムDocletの作成方法が変更されたようだ。
Using the new Doclet API

SampleDoclet.java
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.tools.Diagnostic.Kind;

import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;

public class SampleDoclet implements Doclet {
  private Reporter rep;

  @Override
  public void init(Locale locale, Reporter reporter) {
    this.rep = reporter;
  }

  @Override
  public String getName() {
    // Docletの名前
    return "sampleDoclet";
  }

  @Override
  public Set<? extends Option> getSupportedOptions() {
    // このDoclet用の引数を定義する
    return Collections.emptySet();
  }

  @Override
  public SourceVersion getSupportedSourceVersion() {
    // サポートするソースコードのバージョン
    return SourceVersion.latest();
  }

  @Override
  public boolean run(DocletEnvironment docEnv) {

    Set<? extends Element> includedElements = docEnv.getIncludedElements();
    for (Element element : includedElements) {
      if (element.getKind() == ElementKind.CLASS) {
        rep.print(Kind.NOTE, "クラス名 -> " + element.getSimpleName().toString());
        List<? extends Element> members = element.getEnclosedElements();
        for (Element member : members) {
          if (member.getKind() == ElementKind.METHOD) {
            rep.print(Kind.NOTE, "メソッド名 -> " + member.toString());
          }
        }
      }
    }
    return true;
  }
}
実行結果
> javac SampleDoclet.java -encoding utf8
> javadoc SampleDoclet.java -sourcepath . -doclet SampleDoclet -docletpath . -encoding utf-8
ソース・ファイルSampleDoclet.javaを読み込んでいます...
Javadoc情報を構築しています...
クラス名 -> SampleDoclet
メソッド名 -> init(java.util.Locale,jdk.javadoc.doclet.Reporter)
メソッド名 -> getName()
メソッド名 -> getSupportedOptions()
メソッド名 -> getSupportedSourceVersion()
メソッド名 -> run(jdk.javadoc.doclet.DocletEnvironment)

PSCustomObjectの比較

プロパティ名が同じでも -eq で比較するとFalseになる。
プロパティだけ取り出して、Compare-Objectで比較する。

$a = [PSCustomObject]@{ a = "a" }
$b = [PSCustomObject]@{ a = "a" }
$c = [PSCustomObject]@{ a = "c" }

$np = $a | Get-Member -Type NoteProperty | ForEach-Object { $_.Name }
(Compare-Object -Property $np $a $b).Count -eq 0

# 等しくない例。Falseになる。
(Compare-Object -Property $np $a $c).Count -eq 0

# Equalsおよび-eqでの比較はFalseになる
$a.Equals($b)
$a -eq $b

もう少し簡単な方法ないだろうか

Thunderbirdのメールデータを取得する方法

Import-Module -Name PSSQLite

$database = "C:\Users\<ユーザ名>\AppData\Roaming\Thunderbird\Profiles\<ランダムな文字列>.default\global-messages-db.sqlite"

# 全件取得したい場合はlimit 1を削除する
$query = "select * from messages INNER JOIN messagesText_content ON messages.id = messagesText_content.docid limit 1"

Invoke-SqliteQuery -Query $query -DataSource $database

参考にしたページ
Thunderbirdからメールメッセージを取得するSQLクエリー
Querying Thunderbird's SQLite message database from C# - Stack Overflow

SQLite にアクセスするためのPowerShellのモジュール
PowerShell Gallery | PSSQLite 1.0.3

3秒間ごとにコピーするスクリプト

指定したフォルダ($src)から指定したフォルダ($dest)にコピーするスクリプト
ただし、ファイルやフォルダを一つコピーするたびに3秒待つ。
また、フォルダの更新日付はコピーした日付となる。

$src = "<コピー元のフォルダパス>"
$dest = "<コピー先のフォルダパス>"
$waitSeconds = 3 # 待ち時間(秒)

Get-ChildItem $src -Recurse |
ForEach-Object {
    $isDir = $_.GetType().ToString().Contains("DirectoryInfo")
    $file = $dest + $_.FullName.Substring($src.Length)
    Write-Host "check $file"
    $exists = Test-Path -LiteralPath $file
    if (-not $exists) {
        if ($isDir) {
            Write-Host "make directory -> $file"
            New-Item -Path $file -ItemType Directory
        } else {
            Write-Host "copy file -> $file"
            Copy-Item -Path $_.FullName -Destination $file
        }
        Write-Host "wait $waitSeconds seconds"
        Start-Sleep -Seconds $waitSeconds
    }
}

月ごとのデータをよこ軸に集計する方法

たまに下記のような、月ごとのデータを

name mouth count
Tom 5 2
Jhon 6 3
Tom 6 3

下記のように変換して、
月の遷移を確認したくなることがある。

name 5 6
Tom 2 3
Jhon 0 6

そういう場合は、Group-Objectを使うと便利

PS > $table = [PSCustomObject]@{name="Jhon";mouth=5;count=2},
[PSCustomObject]@{name="Tom" ;mouth=6;count=3},
[PSCustomObject]@{name="Jhon";mouth=6;count=3}

PS > $table

name mouth count
---- ----- -----
Jhon     5     2
Tom      6     3
Jhon     6     3

PS > $table | Group-Object -Property name |
% {
    $a = [PSCustomObject]@{name=$_.name}
    $_.Group | % {
        $a | Add-Member -NotePropertyMembers @{$_.mouth=$_.count}
    }
    $a
}

name 5 6
---- - -
Jhon 2 3
Tom    3