会社支給PCでも使えるPowershell/WSH活用(RPA)

<H2>環境</H2>
Windows10

<H2>概要</H2>
会社支給のデスクトップがごちゃごちゃしがちなのでpowershellとWSHで整理したときのメモ
<H2>背景</H2>
サラリーマンの仕事をしてると、日々資料が溜まっていきます。とりあえずデスクトップにおいておく人も多いのではないかと思います。
結果2~3日で、ごちゃごちゃに。
好きなアプリを入れて整理したいなぁと思っても、会社からの支給PC(Windows10)だとアプリのインストール権限がなくて、自由に入れられない。大企業になればなるほど特にセキュリティがうるさい。
<H2>機能</H2>
そこで、会社の支給PCでも制限なく使えるようにWindows標準のWindows Script Host(WSH)とpowershellを使って、ファイル整理用のスクリプトを作りました。
・見終わったファイルをドロップすると月ごとのフォルダを生成して格納します
・後で見るかもしれないファイルは、デスクトップにショートカットを作ります
・2年経ったら圧縮します(支給PCだと容量が少ない)

<H2>メリット</H2>
ファイルが多くなりがちかつ、アプリのインストールが許容されていない大企業の支給PCのような環境でも使えます

<H2>コード</H2>
<H3>ファイル整理用 Drop2MyDoc_2.js</H3>
デスクトップにおいて、ファイル等をドロップすると、年月のフォルダに移動してデスクトップにはショートカットを作ります。

```javascript
var FORREADING = 1;
var FORWRITING = 2;
var FORAPPENDING = 8;
var TRISTATE_TRUE = -1;   // Unicode
var TRISTATE_FALSE = 0;   // ASCII
var TRISTATE_USEDEFAULT = -2;
var WS_NOTVISIVLE = 0;
var WS_ACT_NORMAL = 1;
var WS_ACT_MIN = 2;
var WS_ACT_MAX = 3;
var WS_NOTACT_NORMAL = 4;
var WS_ACT_DEF = 5;
var WS_NOTACT_MIN = 7;

var toDoubleDigits = function (num) {
    num += "";
    if (num.length === 1) {
        num = "0" + num;
    }
    return num;
};

var sh = new ActiveXObject( "WScript.Shell" );
var fs = new ActiveXObject("Scripting.FileSystemObject");
var baseDir = sh.SpecialFolders("MyDocuments") + "\\works\\new\\";
var dd = new Date();
var targetDir = toDoubleDigits(dd.getYear() % 100) + "" + toDoubleDigits(dd.getMonth() + 1) + "\\";
var desktopDir = sh.SpecialFolders("Desktop");

var args = WScript.arguments;

if(args.length ==0){
	if(fs.FolderExists(baseDir + targetDir)){
		sh.Run("C:/Windows/explorer.exe " + baseDir + targetDir, 1);
	}else{
		fs.CreateFolder(baseDir + targetDir);
		sh.Run("C:/Windows/explorer.exe " + baseDir + targetDir, 1);
	}
}else if (args.length > 0) {
	for (var i = 0; i < args.length; i++) {
		if((fs.GetParentFolderName(args(i)).slice(0,1)!="C" && fs.GetParentFolderName(args(i)).slice(0,1)!="D")){
			//WScript.Echo(fs.GetParentFolderName(args(i)).slice(0,1));
			WScript.Echo("You cannot get file from common directory.");
			WScript.Quit();
		}
		var file = args.item(i);
		if (fs.FileExists(file)) {
			copyFile2Dir(file);
        	} else if (fs.FolderExists(file)) {
			copyDir2Dir(file);
		}
	}
}

function enumFiles(target) {
    if (fs.FileExists(target)) {
        return [target];
    }
    if (!fs.FolderExists(target)) return [];
    var result = [];
    var dir = fs.GetFolder(target);
    var e = new Enumerator(dir.Files);
    for (; !e.atEnd() ; e.moveNext()) {
        var file = e.item();
        result.push(file.Path);
    }
    e = new Enumerator(dir.SubFolders);
    for (; !e.atEnd() ; e.moveNext()) {
        var r = enumFiles(e.item());
        result = result.concat(r);
    }
    return result;
}

function copyFile2Dir(inputFile){
	var ext = fs.GetExtensionName(inputFile).toLowerCase();
	if (ext.indexOf("lnk") == 0) {
		var sfile = sh.CreateShortcut(inputFile);		
		if((sfile.TargetPath.slice(0,1)!="C" && sfile.TargetPath.slice(0,1)!="D")){
			//WScript.Echo(fs.GetParentFolderName(args(i)).slice(0,1));
			WScript.Echo("You cannot get file from common directory.");
			WScript.Quit();
		}
		
		if(fs.FolderExists(baseDir + targetDir)){
			if(fs.FolderExists(sfile.TargetPath)){
				copyDir2Dir(sfile.TargetPath);
			}else{
				if (!(fs.FileExists(baseDir + targetDir + fs.GetFileName(sfile.TargetPath)))) {
					fs.MoveFile(sfile.TargetPath, baseDir+targetDir);
				}
			}
		}else{
			fs.CreateFolder(baseDir + targetDir);
			fs.MoveFile(sfile.TargetPath, baseDir+targetDir);
		}
		//デスクトップにショートカットがいらない場合は削除
		if(!(fs.GetParentFolderName(inputFile) == desktopDir)){
			var shortcut = sh.CreateShortcut( desktopDir + "/" + fs.GetFileName(sfile.TargetPath)+"_shortcut.lnk" );
			shortcut.TargetPath = "file:/" + baseDir + targetDir + fs.GetFileName(sfile.TargetPath);
			shortcut.Save();
		}
    }else{
		if(fs.FolderExists(baseDir + targetDir)){
			if (!(fs.FileExists(baseDir + targetDir + fs.GetFileName(inputFile)))) {
				fs.MoveFile(inputFile, baseDir+targetDir);
			}else{
				WScript.Echo("File exist" + inputFile);
			}
		}else{
			fs.CreateFolder(baseDir + targetDir);
			fs.MoveFile(inputFile, baseDir+targetDir);
		}
		//デスクトップにショートカットがいらない場合は削除
		var shortcut = sh.CreateShortcut( desktopDir + "/" + fs.GetFileName(inputFile)+"_shortcut.lnk" );
		shortcut.TargetPath = "file:/" + baseDir + targetDir + fs.GetFileName(inputFile);
		shortcut.Save();
	}
}
function copyDir2Dir(inputDir){
	//var fileList = enumFiles(inputDir);
	if(fs.FolderExists(baseDir + targetDir)){
		if(!(fs.FolderExists(baseDir + targetDir + fs.GetFileName(inputDir)))){
			fs.MoveFolder(inputDir, baseDir+targetDir);
		}else{
			WScript.Echo("Folder exist" + inputDir);
		}
	}else{
		fs.CreateFolder(baseDir + targetDir);
		fs.MoveFolder(inputDir, baseDir+targetDir);
	}
	//デスクトップにショートカットがいらない場合は削除
	var shortcut = sh.CreateShortcut( desktopDir + "/" + fs.GetFileName(inputDir)+"_shortcut.lnk" );
	shortcut.TargetPath = "file:/" + baseDir + targetDir + fs.GetFileName(inputDir);
	shortcut.Save();
}
sh = null;
```
<H3>ファイル圧縮用 archive_old_dir.ps1</H3>

```powershell
$OutputEncoding = [System.Text.Encoding]::GetEncoding('shift_jis')
Add-Type -AssemblyName System.IO.Compression.FileSystem
function ArchiveDir($localPath, $trashBox, $archiveYM)
{
	$dirItemList = Get-ChildItem -Directory $localPath
	#write-host $localPath
	$nowYM = Get-Date -Format "yyMM"
	#write-host $nowYM

	foreach($item_dir in $dirItemList){
		#write-host $item_dir
		if($nowYM -gt [int][string]$item_dir+$archiveYM){
			#write-host $item_dir
			#Compress
			$trashArchive = Join-Path $trashBox $item_dir".zip"
			Compress-Archive -Path $localPath$item_dir -DestinationPath $trashArchive -Update
			Remove-Item $localPath$item_dir -Recurse -Force
		}
	}
}

#ファイルをアーカイブする期限（日数）=>ダウンロード後、この期間経過するとアーカイブする
#$archiveLimit = 365*2
#2011(2020/11) 2012(2020/12) etc
#100の位が年度の差分 => 200 は2年分
$archiveLimit = 200

###
$mypath=Split-Path ( & { $myInvocation.ScriptName } ) -parent
$dirDest = $mypath+"\" + $Args[0] + "\"
#アーカイブ先ディレクトリ
$trashDest = Join-Path $mypath "old/"

###処理
ArchiveDir $dirDest $trashDest $archiveLimit
```
<H3>呼び出し用バッチ archiver.bat</H3>
archive_old_dir.ps1呼び出し用。スタートアップにショートカットを作っておけば、ログインの度に実行します。

```bat
@echo off
echo Now Scripting
for %%j in (testdir) do (powershell -NoProfile -ExecutionPolicy Unrestricted "Path to archive_old_dir.ps1" %%j)
echo Finished! Press Enter.
pause > nul
exit
```

<H2>参考</H2>
このへんを参考にした記憶。
WSH JScriptを使いこなそう
https://jscript.zouri.jp/
powershell
https://qiita.com/tomoko523/items/df8e384d32a377381ef9
ファイル圧縮
https://soma-engineering.com/coding/powershell/compress-files-zip/2018/07/16/