Powershellと7zipで拡張子を明示しタイムスタンプを継承してパスワード付き圧縮/解凍をする

[今更7-zipのコマンドラインのVBScript](https://qiita.com/Q11Q/items/0d0d41fb858407a74212)
これと同じことをPowershellでもできないか悩んでいたのですが
[Powershellでファイルの拡張子をドット抜きで取得する方法 get extensionname without dot /Period](https://qiita.com/Q11Q/items/d867d72f197d7130b88b)
これができたので、VBSと比較的近い形でPowershellで圧縮することができるようになりました。

##VBSにはない付加機能 zipファイルのタイムスタンプ承継
このスクリプトは1つのファイルを圧縮することを前提にしています。
このため圧縮するファイルのタイムスタンプを取得して、できあがったzipファイルのタイムスタンプが同一になるようにしています。
このためいちいちファイルを開かなければいつのファイルかわからない、ということがなくなります。

```powershell:Compress.ps1
#Ver 20190109
$strFileName ="C:\hoge\hoge.txt" # 圧縮する対象のzipファイル
$strPassWord ='Password' #呪文
$7zip="C:\Program Files\7-Zip\7z.exe" #7zipのある場所
if((Test-Path $strFileName) -eq $true){
$ofile = Get-childItem -Path $strFileName　#ファイルの存在をテスト
if($ofile.PSIsContainer-eq $false){ #ファイルかフォルダか確認
if([string]::IsNullOrEmpty($ofile.extension)){Write-Host "no extention";$strExtension='' #拡張子がなければNullStringを返す
}Else{
$strExtension = ( $ofile.extension.Substring(1,$ofile.extension.Length-1)) ;
Write-Host $strExtension
}
$strBasename= $ofile.BaseName
$strParent= $ofile.DirectoryName
$strNewFileName =(Join-Path $strParent $strBasename)
$strNewFileName += "_"
$strNewFileName += $strextension
$strNewFileName += ".zip"
#Get File timestamp
$DTCr = $ofile.CreationTime
$DTMd = $ofile.LastWriteTime
$DTAc = $ofile.LastAccessTime
Write-Host $strNewFileName
#すでにzipファイルがあるときはskipする
if((Test-Path $strNewFileName) -eq $False){
# 7-Zipのコマンドライン引数を生成
$Arg=" a -y  -p" + $strPassWord + " "+ $strNewFileName +" "+ $ofile.FullName

# 7-zipで圧縮
Start-Process -Wait $7zip -Verb runas -ArgumentList $Arg -WindowStyle Minimized
$ofile = (get-childitem $strNewFileName)
# Set zip file timestamp
$(get-childitem $ofile.FullName).CreationTime=$DTCr
$(get-childitem $ofile.FullName).LastWriteTime=$DTMd
$(get-childitem $ofile.FullName).LastAccessTime=$DTAc
}
} #if($ofile.PSIsContainer-eq $false)
} #if((Test-Path $strFileName) -eq $true)
```

##参考先との埋めがたい実力差
[PowerShellと7zipでファイルを圧縮](https://qiita.com/arachan@github/items/1147915cd0bcc011872f)
ここを参考にしているのだが、うまく動かない。
###動かない点その1 圧縮オプション
これの

```
-mem=AES256 
```

というのはなぜか有効ではなかった。64bitだからだろうか?
###動かない点その2 7z.exeの場所の取得

```powershell

$path=Split-Path ( & { $myInvocation.ScriptName } ) -parent
```

これもダメだった。このため上記コードでは直接実行ファイルのフルパスを書いている。

###動かない点その3 管理者モード

```powershell
Start-Process $7zip -Verb runas -ArgumentList $Arg
```

これは絶対わからない... -Verb runas  が管理者として実行になります。しかしこれはなくても動きます。

#解凍

```powershell:ps_Extractwith7zip.ps1
#Ver 20190109
$strFileName ="C:\hoge\hoge_txt.zip" # 解凍する対象のzipファイル
$strPass = "Password" #呪文
$7zip ="C:\Program Files\7-Zip\7z.exe" #7z.exeのフルパスを記載してください
if((Test-Path $strFileName) -eq $true){
$ofile = Get-childItem -Path $strFileName　#ファイルの存在をテスト
#$strParent = $ofile.PSParentPath.Replace("Microsoft.PowerShell.Core\FileSystem::","")
$strParent=$ofile.DirectoryName
$commandstring = " x -y -p" + $strPass + " " + $strFileName + " -o" +"""" + $strParent +"""" + " -aoa" #問答無用で同名のファイルを上書きする。
Start-Process $7zip -Wait -Verb runas -ArgumentList $commandstring -WindowStyle Minimized
}
```
##-aoスイッチ
-ao (Overwrite mode) switch
-aos Overwrite All existing files without prompt.問答無用で上書き -yスィッチもいれると問答無用度が増す
-aos Skip extracting of existing files.  上とは逆で同名のファイルがあればスキップ。
-aou aUto rename extracting file (for example, name.txt will be renamed to name_1.txt). 
同名のファイルがあれば既存のファイルに枝番を付す
-aot auto rename existing file (for example, name.txt will be renamed to name_1.txt). 
同名のファイルがあればいまから解凍しようとするファイルに枝番を付す。
普通の枝番をつける方法はこれ。 -aouはちょっと珍しいし、既存のファイルの方をいじるのは感心しない。
##-oについて
この後ろが出力先フォルダですが、どこにも書いていないけど、スペースが入っているフォルダの場合はダブルクォーテーションで囲んだ方がよいようです。

##参考
[17.ファイルの存在するディレクトリパスを取得する](http://hiros-dot.net/PowerShell/file/file17.htm)

##VBS版
こちらに記載しています。
https://qiita.com/Q11Q/items/0d0d41fb858407a74212