0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PowerShellを使ったファイル操作

Last updated at Posted at 2021-05-15

マルウェアでPowerShellが使われる場合があると聞いたことがあったので、セキュリティの知識向上のためPowerShellの勉強(プログラミング)を始めました。何を作っていいかわからなかったので、とりあえず自分が使いそうなファイル操作のサンプルを試しに作りました。

ファイル名の数値を同じ桁数にする

対象となるフォルダのツリー構造で表示します。

実行前
C:.
│  oya_1.txt
│  oya_10.txt
│  oya_11.txt
│  oya_2.txt
│  oya_3.txt
└─ko
    │  ko_1.txt
    │  ko_10.txt
    │  ko_11.txt
    │  ko_2.txt
    │  ko_3.txt
    └─mago
            mago_1.txt
            mago_10.txt
            mago_11.txt
            mago_2.txt
            mago_3.txt

ファイル名に数値を使っている場合、上のような順番に並んでしまい見栄えが良くない場合があります。数値を3桁に変更することにより、並び順を変えて見やすくします。

プログラム
Get-ChildItem -Recurse | ForEach-Object {if ($_.Name -match '\d+') {
$n = $_.Name -split $Matches[0],2
Rename-Item -Path $_.FullName -NewName ($n[0]+'0'*(3-$Matches[0].Length)+$Matches[0]+$n[1])
}}
実行後
C:.
│  oya_001.txt
│  oya_002.txt
│  oya_003.txt
│  oya_010.txt
│  oya_011.txt
└─ko
    │  ko_001.txt
    │  ko_002.txt
    │  ko_003.txt
    │  ko_010.txt
    │  ko_011.txt
    └─mago
            mago_001.txt
            mago_002.txt
            mago_003.txt
            mago_010.txt
            mago_011.txt

全角で書かれたファイル名を半角にする

対象となるフォルダをツリー構造で表示します。

実行前
C:.
│  TEST1.txt
└─FOLDER1
    │  TEST2.txt
    └─FOLDER2
            TEST3.txt

ファイルとフォルダを全角から半角に変換します。

プログラム
using namespace Microsoft.VisualBasic
Add-Type -AssemblyName 'Microsoft.VisualBasic'
Get-ChildItem -Recurse | ForEach-Object { Rename-Item -Path $_.FullName -NewName ([Strings]::StrConv($_.Name,[VbStrConv]::Narrow)) }
実行後
C:.
│  TEST1.txt
└─FOLDER1
    │  TEST2.txt
    └─FOLDER2
            TEST3.txt

サブフォルダを含むファイル名の出力

子や孫フォルダを含むファイル名を出力します。csv形式で出力する場合と、フルパスのみ出力する場合の2パターンを記載します。なお、文字化け対策としてUTF-8でコード変換して出力しています。

csv形式の出力
Get-ChildItem *.txt -Attributes Archive -Recurse | Select-Object DirectoryName,BaseName,Extension,Length,LastWriteTime | Export-Csv -Encoding UTF8 output.csv
output.csv(実行結果)
# TYPE Selected.System.IO.FileInfo
"DirectoryName","BaseName","Extension","Length","LastWriteTime"
"C:\Users\test\FOLDER1\FOLDER2","TEST3",".txt","10","2021/05/01 12:00:00"
"C:\Users\test\FOLDER1","TEST2",".txt","10","2021/05/01 12:00:00"
"C:\Users\test","TEST1",".txt","10","2021/05/01 12:00:00"
フルパスのみの出力
Get-ChildItem *.txt -Attributes Archive -Recurse | ForEach-Object { $_.FullName } | Set-Content output.dat
output.dat(実行結果)
C:\Users\une\test3\FOLDER1\FOLDER2\TEST3.txt
C:\Users\une\test3\FOLDER1\TEST2.txt
C:\Users\une\test3\TEST1.txt

ファイルに書かれているファイルを集める

先程出力したファイルoutput.datを元に、ファイルを現在のパスにコピーします。なお、同じファイル名がある場合はコピーしません。

プログラム
Get-Content output.dat | ForEach-Object { if (Test-Path $_) { Copy-Item -Path $_ -Destination . } }
実行結果
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2021/05/01     12:00             10 TEST1.txt
-a----        2021/05/01     12:00             10 TEST2.txt
-a----        2021/05/01     12:00             10 TEST3.txt

サブフォルダも含むファイル内容の検索

対象となるフォルダのツリー構造で表示します。

対象フォルダ
C:.
│  test1.txt
└─folder1
        test2.txt
test1.txt
ABCDEFGHIJ
1234567890
abcde12345
test2.txt
ABCDEF
123456
ABC123

select-Stringは正規表現も可能です。

プログラム
Get-ChildItem -Recurse | Select-String -Pattern 'c\w' | Select-Object path,LineNumber,line
実行例
Path                                 LineNumber Line
----                                 ---------- ----
C:\Users\une\test4\test1.txt                  1 ABCDEFGHIJ
C:\Users\une\test4\test1.txt                  3 abcde12345
C:\Users\une\test4\folder1\test2.txt          1 ABCDEF
C:\Users\une\test4\folder1\test2.txt          3 ABC123

おわりに

今回は(本当に初めてだったので)ファイル操作だけでしたが、次からはよりセキュリティに近いイベントログを集計したり、システムを自動操作できるスクリプトを組んでみたいと思います。

0
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?