# cmdからのcsharpとPowershellへの移行とパフォーマンス
---
## 皆さんこんにちは!
:wave:
---
<!--
初めましての方も多いと思いますので自己紹介させて
いただきます。
フリーランスのバックエンドエンジニアをやっております
音川といいます。
-->
## My Profile
## Otogawa Katsutoshi
### go, python, Powershell,Linux
### freelance backend enginner
---
<!-- 今回私が何しに来たか?というと -->
## 皆さんそろそろ考えていると思うのですよ
---
## cmdからPowershellへの移行を

<!--
ここで
-->
---
## なぜしないといけないかというと
cmdはメンテナンスモードで、後方互換性のために残されているから。
msとしても無くして行きたい方針。
https://x.com/richturn_ms/status/1265155820083240962
---
## 今はほとんどのものがpowershellでできる
昔はwindowsの機能の多くはcmdのコマンドアプリケーション触らないといけないものが多かったが、
今は多くがPowershellから操作できる。
<!--
今、私が使っているこのパソコンも
windows11 の評価版のimageをダウンロードして、初期起動したらええ感じの設定になるようにosのimageを自分で作成してそれを外付けのSSDにインストールしています。
そういうWindowsのOSの機能も基本Powershellで完結していて、
これはcore系のPowershellでもできます。
-->
---
## よって今はpowershellでも機能的には困らない。
---
## ところが、ここでバッチを書くときに問題になることがあります。
---
## powershell遅過ぎ問題

---
## パフォーマンスは基本的に
計測どころか体感できるレベルの差。
csharp > cmd >> powershell
場合によってはPowershellは数10万レコードとってきただけで遅くなる。
(core系でも.netframework系でも同じ。)
(大なりがパーフォーマンス良いほう)
---
## cmdからPowershellにしたらパフォーマンス的に動かなくなるバッチ処理は普通に出る

---
## Powershell自体を早くしたい!
---
## あきらめてください。
---
## 早くするコツ
1. ForEach-Object使わない。文法のほうのforeach使う
2. Test-何々を使わないifを使う。
---
## 作業としてPowershellのコマンドレットを制御構文に置き換えていくことになる。
---
## 結論、バッチ全部csharpでええやん

---
## ここでまた問題が起きる
---
## dotnetはwindowsのすべての機能をサポートしているわけではない
Powershellにしかない機能もある
- BitLocker
- Storage(低レイヤー)
- DISM
- Hyper-V
---
## dotnetよりもpowershellのほうが楽に変更できるものもある
- ActiveDirectory
- GroupPolicy
- Network回り
- DNS
---
## dotnetから操作できなくてPowershellになぜあるか?
クローズドなソースコードでC:\Windows\System32\WindowsPowerShell\v1.0\Modules\配下に内部的に下記のモジュールになっている
1. CIMClassのメソッドを実行(Storageなど)
2. Win32APIを包むスクリプトモジュールを使ってコンパチな処理(BitLockerなど)
3. APIを包むバイナリモジュールを作ってそこから操作(Hyper-Vなど)
---
## これらをchsarpを使って自分たちで実装して運用するのはかなり難しい。
-> どこかでpowershellを使う必要がある。
自分たちで実装するならドキュメントガリガリ読む必要がある。辛い。
https://learn.microsoft.com/ja-jp/windows/win32/secprov/win32-encryptablevolume
<!--
-->
---
## なので、Powershellも使う必要がある
パフォーマンスのためにcsharpに全部寄せれない!困った!

---
## これらを解決したい
---
## Powershell SDKを使おう!
csharpからPowershellを操作できるPowershellSDKなら
csharpですべて完結できる。
```powershell=
dotnet add package Microsoft.PowerShell.SDK --version 7.4.2
```
---
## Powershell SDKの特徴
1. Powershellが内部で使っている処理なのでバグがある可能性は低い。
2. SQLのOrmマッパー、クエリビルダみたいに書いていける。
3. Powershellはインストールする必要がない。
4. バッチごとにPowershellのバージョンを指定して管理できる。
dotnet 5.0以降の自己完結型のシングルバイナリ作ってあげたらgoみたいにそれだけ持っていくと動作するということが可能。
---
## ソースコード例
---
## 基本1
```powershell=
Get-ChildItem -Path C:/Windows
```
ならこんな感じ
```powershell=
using System;
using System.Management.Automation;
// PowerShellのインスタンスを作成
using (PowerShell powerShell = PowerShell.Create())
{
// PowerShellコマンドを追加
// Get-ChildItem -Path C:/Windows
powerShell.AddCommand("Get-ChildItem")
.AddParameter("Path", "C:/Windows");
// コマンドを実行し、結果を取得
var result = powerShell.Invoke();
// 結果を出力
foreach (var item in result)
{
Console.WriteLine(item.TypeNames);
Console.WriteLine(item.BaseObject.ToString());
}
// エラーがあれば表示
if (powerShell.HadErrors)
{
foreach (var error in powerShell.Streams.Error)
{
Console.WriteLine(error.ToString());
}
}
}
```
---
## 基本2
ScriptBlockがある場合
```powershell
Get-ChildItem -Path C:/Windows | ForEach-Object {echo "FullName: $($_.FullName)"}
```
```dotnet=
// 長いので中略
var scriptBlock = ScriptBlock.Create("echo \"FullName:$($_.FullName)\"");
// AddCommandをつないでいくとパイプ処理
var result = powerShell.AddCommand("Get-ChildItem").AddParameter("Path", "C:/Windows").AddCommand("ForEach-Object").AddParameter("Process", scriptBlock).Invoke();
```
---
## 基本3
スクリプトモジュール実行
```dotnet=
// 実行ポリシーを変更
var result = powerShell.AddCommand("Set-ExecutionPolicy")
.AddParameter("Scope", "Process")
.AddParameter("ExecutionPolicy", "RemoteSigned")
.Invoke();
// 自動でImportされていないモジュールはImport-Moduleでインポートする。
// Scriptモジュールで定義されている関数はコマンドではなくて関数なので
// Add-Scriptを使う。
result = powerShell.AddScript("Get-Disk")
.AddParameter("Number", 0)
.Invoke();
```
---
## デメリット
1. core系のPowershellでないと気軽に使えない
2. dotnetからPowershellのインスタンスを作るときに結局時間はかかる。
目標としてはPowershellだけより、Powershellのソースコードを減らせれる。と考えたらよい。
---
## まとめ
<!-- に入らせて頂きますと、 -->
1. Powershellは遅い。パフォーマンス的にはcsharp使ったほうがいい。
2. dotnetに無いものはPowershellを使う。
3. dotnetからPowershell SDKを使うとcsharpでほぼすべて完結できる。
4. Powershell SDKを使うと個々のバッチごとにPowershellのバージョンを指定できる。
という理由からcmdからの移行にはcsharpを使って必要に応じてpowershell SDKを使うのがよいがと思います。
<!--
という事だけ覚えて頂けたら幸いです。
ご清聴ありがとうございました。
-->

---
## プレゼンする私の知識
<!--
としては
-->
1. AIの仕組みをなんとなく知っている
2. windowsは普通の人より理解している
3. Powershellはチョットワカル
<!--
程度です。
-->
---
apiからAIを使うエンジニアとして話します。
ご了承ください。

<!--
という事で本題に入ります。
-->
---
## そもそもPowershellって?

---
## Powershellとは
Windowsにおけるcmdに代わるシェル
Windowsのみで動く5.1系以前と
macやLinuxでも動く6系以後と2種類ある
<!-- 次に -->
---
## PowershellAIとは?

---
## PowershellからOpenAIを使うためのモジュール
API経由でOpenAIが提供しているモデルを使う。
GPT3とか。
<!-- まだこのモジュールに -->
最近話題のChatGPTが使えるようには実装されていない。
<!--
けど、そのうちPowershellのモジュールらしく使えるように実装されると思います。
このモジュールは
-->
---
## 出来たばっかり
PSGalleryに登録して2ヶ月ちょっと。
生まれたばかりのモジュールです。

---
## 面白い点として
モジュールが提供する、copilotコマンドでPowershellスクリプトを出力する事ができる。
<!--
github copilotとは何の縁もないですが、copilotです。
-->
---
<!-- という事でここからは PowershellAIの -->
## 使い方
<!--
の流れを説明します。
まずは
-->
---
## 1. モジュールをインストール
<!-- します。 -->
```powershell
PS /Users/katsutoshi> Install-Module PowershellAI
```
<!-- 環境変数の設定 -->
---
## 2. 環境変数の設定
環境変数OpenAIKeyにOpenAIのapiキーを入れておく。
```bash
echo export OpenAIKey="yourkey" >> ~/.bash_profile
```
<!--
ここで注意なんですが、
**python のopenaiと環境変数名が違うので注意。pythonはOPENAI_API_KEY**
-->
---
## 3. copilotコマンドを実行する
下のように文字列を渡して実行する
例えば、「郵便番号をcsvで取得して」と英語で文章を渡します。
```powershell
PS C:\Users\science> copilot "Get Postalcode csv from japanese post office"
```
<!--
すると
-->
---
## 4. スクリプトが出力される
下のようなPowershellのスクリプトが返ってくる。
```
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Get Postalcode csv from japanese post office ║
║════════════════════════════════════════════════════════════════════════════════════════════════════════════════════║
║1: Invoke-WebRequest -Uri "https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip" -OutFile "ken_all.zip" ║
║2: Expand-Archive -Path "ken_all.zip" -DestinationPath "." ║
║3: Get-ChildItem -Path "ken_all.csv" ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
```
---
<!--
-->
## ね!簡単でしょ!

<!--
ただ、問題点としては
-->
---
## 架空のモジュールやコマンドレッドを~~しれっと~~自作する
どや、出来たやろ?

ただ、簡単なことだったら、そこそこ答えられる
<!--
なので、
どの程度の難しさならできるのか?を調べるために実践的かつ難しい事を聞いてみます。
ここでは試しに
-->
---
## 「powershellからwindowsの~/.sshに適切な権限を与えて」と聞いてみます。
え?簡単でしょ?とか思う人もいると思うんですが、

---
## 実は難しいことを聞いている
暗黙的に下記の知識が問われる
1. Set-Aclの権限削除のバグ(MSが放置している)<!-- どういうバグかというと、自分が所有者のファイルでさえ、他の人のアクセス権限をなくすのに管理者権限がいるっていう致命的なバグです。 -->
2. windowsにおける~/.sshの適切な権限の処理 <!-- これはあまり書かれているサイトがない。 -->
3. Set-Aclで一度に設定できない権限の理解 <!-- 2回に分けて権限の操作をする必要がある。エラーがでないけど、正しく権限が設定されない。
これはちゃんと説明ある場合は、仕様と言い張るなら仕様でバグじゃないです。
しかし、説明ないからバグみたいなもんですね。
-->
---
## Set-Aclのバグのレベルとしては
お前、ホンマにリリース前にデバッグしたか?というレベル

<!--
これは自分の想像なんですが、多分
-->
---
## 管理者権限で動いたからヨシ!
<!-- っていう事でそのまま放置しているんだと思います。 -->

<!--
で知らない人はそんなバグあるとは想像つかないので、
-->
---
## プログラマーがとばっちりを受ける
<!--
と。
-->

---
## こまけぇ事は良いんだよ:laughing: !
<!-- ってことで。
冷静になって、
-->
「パーミッションの操作バグが何年も放置されているshellって何?」とか考えちゃダメです。

<!-- という事で、以上の本題のプログラムを -->
---
## 組み立てるとこのような処理になる
1. 権限の継承を無効にする。
```powershell
# ~\.sshの権限を取得する
$acl = Get-Acl ~\.ssh
# 権限の継承を無効にしたうえで、現在の権限は保持する。
# [system.security.accesscontrol.objectsecurity.setaccessruleprotection](https://learn.microsoft.com/ja-jp/dotnet/api/system.security.accesscontrol.objectsecurity.setaccessruleprotection?view=net-7.0)
$acl.SetAccessRuleProtection($True, $True)
# 権限の反映を行う
Set-Acl -Path ~/.ssh -AclObject $acl
```
<!--
一度権限の継承を無効にしないと権限の操作ができないので、こうする必要があります。
-->
---
## 2. 自分以外のユーザーの権限をなくす
Set-Aclで権限を削除できないので、csharpのクラスを使う必要がある。
```powershell
# ユーザーのホスト名と名前を取得する。
$hostname = $env:USERDOMAIN
$username = $env:USERNAME
$acl = Get-Acl -Path ~/.ssh
# 指定のユーザー以外のアクセス権限をすべて削除する。
# Remove-Aclコマンドとかないので、ループで回して消す必要がある。
$acl.Access |
Select-Object -ExpandProperty IdentityReference |
?{$_ -notin ("$hostname\$username", "NT AUTHORITY\SYSTEM", "BUILTIN\Administrators")} |
%{$acl.PurgeAccessRules($_)}
# ユーザーから権限を無くすときはSet-Aclは使えない。なので、下記のクラスメソッドを使う必要がある。
# [system.io.filesystemaclextensions.setaccesscontrol](https://learn.microsoft.com/ja-jp/dotnet/api/system.io.filesystemaclextensions.setaccesscontrol?view=net-7.0)
[System.IO.FileSystemAclExtensions]::SetAccessControl((Get-Item ~/.ssh), $acl)
```
---
## AIがこれらの知識を組み立てれるか?
以上の処理が一貫して書かれているスクリプトは
英語で探しても日本語で探してもzennの自分のサイトしかない。
<!--
なので、できるなら知識を組み立てれてると言って良いです。
で
-->
---
## 実際聞いてみる
<!-- 下に -->
一番もっともらしいのが表示されたやつ。
<!-- を乗っけています。 -->
```powershell
PS C:\Users\science> copilot "Set proper permissions to ~/.ssh in windows"
```
```
╔════════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Set proper permissions to ~/.ssh in windows ║
║════════════════════════════════════════════════════════════════════════════════════════════║
║1: $acl = Get-Acl -Path ~/.ssh ║
║2: $permission = "Users","FullControl","ContainerInherit,ObjectInherit","None","Allow" ║
║3: $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission ║
║4: $acl.SetAccessRule($accessRule) ║
║5: Set-Acl -Path ~/.ssh -AclObject $acl ║
╚════════════════════════════════════════════════════════════════════════════════════════════╝
```
<!--
これは
ユーザーにフルコントロールの権限与える程度で
特になんもやっていない。
という事で、
-->
---
## 現段階ではソースコードを出力するという用途ではポンコツ
「総合的にはググった方が確実かつ早い」と思った方がいい。
AIが発達してもこの精度が上がるだけのはず
<!--
結局SFでよくある
-->
---
## AIが考えたことに従う未来
なんて来なくて

<!-- 今まで通り -->
---
## 考える作業は人力です
安心してください!
皆さんの仕事は無くなりません :sob: !

<!--
じゃあここで、エンジニアとして
-->
---
## PowershellAIで楽にできること
<!--
について最後にまとめます。
-->
1. 情シスや、運用エンジニアの定型業務 <!-- 殆どがHelloWorldの域を出ない。しかし、ネットワークの設定は結構そのまま使えるものが出たりする。 -->
2. MSの商品に依存したスクリプト作成 <!-- これはよにあるPowershellのスクリプトの殆どがMSの商品を使ったものだからです。 -->
<!--
Sierとかでwindowsを日常的に使って仕事している人は今までより仕事楽になる可能性はある。
Sierとかお堅いところは中々、申請通らんかもだけど、すぐ導入したらええんじゃないかなと。
-->
<!--
さっき言ったネットワークの設定も実は怪しくて、
Set-NetAdapterWiFiっていう存在しないコマンドレット使ってパスワードの設定をしようとしていた。
Powershellにwifiのパスワードを設定するコマンドレットが存在しないから、cmdやらCsharpをこねくり回して設定する必要がある。
Set-NetIPInterfaceにCredentialを渡すというスクリプトが表示されたけど、Set-NetIpInterFaceにはCredentialを渡す引数はない。
動作するかどうかわからないスクリプトを使って学習しているから。
-->
---
<!--
という事で発表内容は以上になります。
-->

---
1. 無いものや言葉を勝手に作る
Powershellを使ってwindows server2022の脆弱性をインストールと書いたら、
copilot "Install Powershell Vulnerability to windows server 2022"
Import-module PSVulnerability
って表示されて、これにwindows server 2022の脆弱性あるのかと思ったら、
そんな事なかった。
2. 知識が無いとググる以上に振り回される可能性がある。
3. 正しい英語を使う必要があるtoとか前置詩おかしいだけで、ちゃんとしたやつとれるかどうかが分かれる。
聞き方微妙に変えたらいい。
PS C:\Users\science> copilot "Register JobTrigger to heck SQL Server Vulnerability"
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Register JobTrigger to heck SQL Server Vulnerability
║
║════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════║
║1: Register-ScheduledJob -Name "Check SQL Server Vulnerability" -Trigger (New-JobTrigger -Once -At (Get-Date).AddMinutes(5)) -ScriptBlock {Invoke-SqlVulnerabilityAssessment -ServerInstance "MyServer\MyInstance" -Database "MyDatabase"} ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
これもInvoke-SqlServervulnerabilityというコマンドはそもそも無い。
あなたがやりたいのは
そもそも、JobTriggerから毎週金曜日脆弱性のチェックなんて、まどころっしい事せずにSqlserver自体に脆弱性の定期実行を登録するものがあったらそれ使ったらいい。
googleで検索したらそもそもできないものは、
一番問題だと思ったのはもっともらしい嘘をつくということ。
---
##
去年2022年のノーベル物理学賞に量子のもつれ
光は粒子の性質調べる観測機器を使うと粒子の性質を
と波の性質を調べる観測機器を使うと波の性質を持つことが分かった。
これは相反する性質なのでどう説明したらいいかわからなかった。
ボーアはこれを粒子として観測すると粒子としての性質を持つし、波として観測すると波の性質を持つ。と主張した。
それはズルい。投げやりやんとアインシュタインは突っ込んだ。
ボーアも冷静に考えると意味不明の事を言っているわけじゃなくて見たまんま解釈して説明しているだけ。
じゃあ、こういう説明だったらどうだ?
ボーアはアインシュタインが
赤色のたまと青色のたまがここにある。
箱に赤色のたまと青色のたまを入れたら、
箱の中には何が入っているでしょう?
アインシュタインは赤色と青色のたまでしょ?当たり前だろ?
ボーアはいや、赤色と青色の状態が混在したたまが2つ入っていると答えた。
アインシュタインはたまの観測の仕方によって結果は変わらない。
結果は観測者から見ると隠れた変数によってすでに結果は決まっている。と答えた。
結果に影響を与えないようにこっそり観測すると、確率が変動するという事を発見した。
アインシュタインの言っていた「隠れた変数」というものはない。
現象を説明変数があるという考え自体がおかしい。
ボーアのいう実際に観測したかどうかによって決まるし、観測の仕方によって結果が決まるが正しいということが分かった。
数学の世界では正しいか、正しくない
だけでなくそもそもわからないというのがあるという証明されたし、
論理の世界でも最近はTrueかFalseだけでなくてunknownという
三値であるという事がわかった。
データベースやプログラミングの世界でNullを完全に撲滅できないのは、
nullがunkownも兼ねているからという理由があって、
AIもこれらと同じでAIの結果をどう観測するかと観測の仕方によって結果が決まるっていう話だと思っている。
つまりどう解釈するかで決定される問題。
アインシュタインも筋通っていて、直感的だけど
冷静に考えるとえー?そうかな?言い切って大丈夫?って言うこと言っていてて、
例えば、私はこの服を今日この服を選んだ事もユニクロのこの位置に服があって、それに去年の10月に目をつけて私が服を買って、それを今日来たのも変数で表現できる。すべて必然でありたまたまということはありえない。
なんか宗教みたいですね。
これは偶然性というのを否定しているし、
つまりどういうことかというとアインシュタインの考え方が常に正しいとすると、いくつかの説明を使って原因から結果にこじつけているということが起こりうる。
50個くじがあって、この中にあたりのくじがある。
くじを全く引いていないときと30個くじを引いてすべてハズレであると確認したあとで、残りのくじにあたりがある確率が変動していないと主張している事になる。
例えばAさんがくじを一つ引いて、まだ開けてないとするとAさんからすると、1/50の確率だけど、まだ開けてない状態でAさんが引いたのはハズレくじだよと教えた場合はAさんが持っているくじの確率はいくつか?
1/50なのか、外れていると分かっているから0なのか?
Aさんの視点からすると1/50出辺りで、これはあたりとハズレの状態が混在しているということになる。
Aさんから見ると観測者の私がそういえば、あたりくじって何番だったっけ?と思って調べるつまり観測すると、ハズレであることが確定する。
だったのが0になったということになる。
私からみると最初からAさんは0。
これと同質の問題を数学者でも間違える人は多い。
思考実験で運と偶然性が大きな影響を与えるという事が一般的になってきている。
---
## oracleに入れてみる
PS C:\Users\science> copilot "Import Postalcode csv to Oracle Database from japanese post office"
```
╔════════════════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Import Postalcode csv to Oracle Database from japanese post office ║
║════════════════════════════════════════════════════════════════════════════════════════════════════║
║1: $csvFile = "C:\PostalCodes.csv" ║
║2: $connectionString = "Data Source=MyOracleDB;User Id=myUsername;Password=myPassword;" ║
║3: $bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $connectionString ║
║4: $bulkCopy.DestinationTableName = "PostalCodes" ║
║5: $bulkCopy.WriteToServer([System.Data.DataTable]::new([System.IO.File]::ReadAllLines($csvFile))) ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════╝
```
<!--
oracleはちょっとおかしい。
これもSQLserverの関数。
ちゃんとPowershellからOracleの操作を行えるcsharpのライブラリもあるので、これは単純にAIが頭悪いですね。
-->
---
## ちなみに
ちなみにOracleDatabaseというPowershellのモジュールは存在しません。
コイツ架空のコマンドレットとか、モジュールとか、引数とか頻繁にしれっと出力するんでね。
## Oracleのデータベースをインストール
自動化するためには次のスクリプトになる
1. oracleのサイトにログイン(idとpassword)
2. セッション持ったままダウンロードのpreinstallとdatabase本体のurlを叩く
3. yum installでpreinstallをインストール
4. /u01/app/oracle/product/19.0.0/dbhome_1の作成して所有者を/u01/app/にoracleにする。
5. /home/oracle/.bash_profileにoracleORACE_HOMEやORACLE_BASEの設定
6. oracleのパッチを充てるASMなどの設定
<!--
他にもネットワークの設定とかいろいろあるけど、ある程度ができたら、まあいいかなという感じ。
スクリプトの難易度的にはLinuxの運用してますとか、
Oracleの運用で触れますっていうなら、書けて欲しい難易度。
.bash_profileとか、yumとか、環境変数とかパッチとか
curl叩いたりとか重箱の隅つつく様なこと聞いてないので、
オンプレ、vps,クラウド問わず実務で触った事あるプログラマならかけてほしいレベルかなと。
簡単なスキルチェックには良さそう。
-->
---
## ゴールとしては
これのwindows版かLinux版を出力してくれたらよい。
<!--
exeになって管理者権限必要とかそういうので完全自動化無理とかは
仕方無いけど、それ以外は技術的にできるはず。
-->
---
## ざっくばらんに聞いてみる
```powershell=
copilot "How to install Oracle database"
```
---
## さて、果たしてどこまで自動でできたでしょう?
<!--
じゃじゃん!
-->
---
## 出力は
```powershell=
PS C:\Users\katsutoshi> copilot "How to install oracle database"
```
```txt
╔═══════════════════════════════════════════════════════╗
║Q: How to install oracle database ║
║═══════════════════════════════════════════════════════║
║1: # Install Oracle Database ║
║2: # Step 1: Download the Oracle Database Software ║
║3: # Step 2: Install the Oracle Database Software ║
║4: # Step 3: Create a Database ║
║5: # Step 4: Configure the Oracle Network Environment ║
║6: # Step 5: Create Additional Databases ║
║7: # Step 6: Create Database Users ║
║8: # Step 7: Configure Database Backup and Recovery ║
║9: # Step 8: Configure Database Security ║
║10: # Step 9: Configure Database Performance ║
║11: # Step 10: Configure Database Auditing ║
║12: # Step 11: Configure Database Monitoring ║
║13: # Step 12: Configure Database Maintenance ║
║14: # Step 13: Configure Database Replication ║
║15: # Step 14: Configure Database High Availability ║
║16: # Step 15: Configure Database Disaster Recovery ║
╚═══════════════════════════════════════════════════════╝
```
---
## まさかの匙を投げるw
どこかの本かサイトのチャプターをそのまま拾ってきたような出力
<!--
ここは
-->
---
## 聞き方が悪いと思って変えてみる
```powershell=
PS C:\Users\science> copilot "Install OracleDabase from Oracle Site"
╔═════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Install OracleDabase from Oracle Site ║
║═════════════════════════════════════════════════════════════════════════════════════════║
║1: # Download the Oracle Database software from the Oracle website ║
║2: $url = "https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html" ║
║3: $file = "oracle19c.zip" ║
║4: Invoke-WebRequest -Uri $url -OutFile $file ║
║5: # Unzip the Oracle Database software ║
║6: Expand-Archive -Path $file -DestinationPath . ║
║7: # Install the Oracle Database software ║
║8: $installer = Get-ChildItem -Path .\database_home* -Directory ║
║9: $installerPath = Join-Path -Path $installer.FullName -ChildPath "runInstaller.sh" ║
║10: & $installerPath ║
╚═════════════════════════════════════════════════════════════════════════════════════════╝
Run the code?
```
<!--
ちゃんんとできてるように見えるが、
htmlファイルを.zipとリネームしてdownloadしてるだけ。
なので、回答できないし、インストールもできない。
惜しいなと思って、
-->
---
## もっと簡単に聞いてみる
```powershell
PS C:\Users\science> copilot "Install OracleDabase"
╔════════════════════════════════╗
║Q: Install OracleDabase ║
║════════════════════════════════║
║1: Install-Module OracleDabase ║
╚════════════════════════════════╝
Run the code?
```
---
## 違う、そうじゃない:worried:
Oracle Databaseをインストールしたい。
Powershellのモジュールをインストールしたいわけでない。

## これについては
<!--
プロダクトアウトの会社がどうやってほしいものを作るのかという話になるんですが、
-->
 
<!--
「アイデアの作り方」という本があるのでそれを見る
昔からある本だけど、これが一番安定して評価高い。
これは実は戦前の本なんだけど、今でも十分通じると言われています。
内容としては100Pもないので、迷うぐらいだったら買ったらいいと思います。
よくある変な経営者が出してる自分のセミナーやコンサルを売るための自己啓発本みたいに本人がやったかどうかわからないことを自身持って書いてるんじゃなくて、
本の通りやってもうまくいくかどうかわからないと正直に書いてあるのがポイント高い。
ここから購入しても私にアフィリエイトとしてお金発生するわけじゃないので、
図書館にも置いてあるところ多いので、
-->
これからはプロダクトマネージャだとか、マーケターだ、いやいやAIだ、日本は商社が強いから営業マンだとかやっていると、世間の流行や、行政に振り回されて急にはしご外される恐怖が常に付きまとう。
特にフリーランスか、経営者なら流行のはしご外されるだけで、事業潰れる可能性あるから割と深刻。
---
## 急にはしご外される可能性がある

---
## コツとしては
コメントとして書かれていそうな事を書くという事。
ブラウザだとHow to とかWhere is とか5W1Hの疑問形だと結構引っかかるけど、
プログラムのコメントは基本的に命令形なので、命令形で伝えると欲しいの拾ってくるっぽい。
---
##
PS C:\Users\science> copilot "Create Active Directory User from csv list"
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Create Active Directory User from csv list
║
║══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════║
║1: Import-Csv -Path "C:\Users\User\Desktop\users.csv" | ForEach-Object {
║
║2: New-ADUser -Name $_.Name -GivenName $_.GivenName -Surname $_.Surname -SamAccountName $_.SamAccountName -UserPrincipalName $_.UserPrincipalName -DisplayName $_.DisplayName -Path $_.Path -AccountPassword (ConvertTo-SecureString -AsPlainText $_.Password -Force) -Enabled $true ║
║3: }
║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
## csvからデータベースにimportする
よくある定型業務。
<!--
ですね。実際に次のように
-->
---
## SQLServerにデータ入れる
<!--
スクリプトをPowershellAIで生成させてみます。
-->
下記の英語の文章を与えて生成させてみる。
```powershell
copilot "Import Postalcode csv to SQL Server from japanese post office"
```
<!--
でこの文字列を与えると次のような
-->
---
## 出力
```
╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║Q: Import Postalcode csv to SQL Server from japanese post office ║
║═════════════════════════════════════════════════════════════════════════════════════════════════════════════║
║1: $csv = Import-Csv -Path "C:\Path\To\Postalcode.csv" ║
║2: $sqlConnection = New-Object System.Data.SqlClient.SqlConnection ║
║3: $sqlConnection.ConnectionString = "Server=MyServerAddress;Database=MyDatabase;Integrated Security=True;" ║
║4: $sqlConnection.Open() ║
║5: $sqlBulkCopy = New-Object System.Data.SqlClient.SqlBulkCopy($sqlConnection) ║
║6: $sqlBulkCopy.DestinationTableName = "Postalcode" ║
║7: $sqlBulkCopy.WriteToServer($csv) ║
║8: $sqlConnection.Close() ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
```
<!--
ものとしては手直ししないといけないが、
-->
---
## ちゃんと実践的なのできてる!
---
## これ見て
PowershellだからSqlserverの例がネットに沢山転がっているからできるのでは?他のRDBMSだと出来ないのでは?

<!--
って突っ込まれる人思います。
-->
---
## その通りです!
Oracleやpostgresqlだろうが、SQLServerと思って処理します。

<!--
多分PowershellでRDBMSの処理しているのが、SQLServerが殆どで、
AIのモデルからすると他のRDBMS自体がバグや間違いに見えるんでしょうね。
後、分からんのやったら分からんでいいんですが、タチ悪いのが、
-->
## 実際やった例を混じえて
現時点でPowershellAIで
1. 何ができるか
2. 出来ない事や微妙なもの
3. 我々がどのように楽になるか?
<!-- 駆け足ですが、 -->
説明していきます。
---
## じゃあもっとpowershellでやることが多そうな事をやってみます。

<!--
時間無いので、
-->
---
## GPT3がどの程度考えられるか?
を説明するために簡単な思考実験をしてみます。
```
内容としては
「プログラマ不要論を満たせるぐらいの将来性はあるか?」
に絞ってやってみます。
```
<!--
でプログラマ不要論を満たせるレベルの条件を
考えたら、次のようなものが良いかなと思います。
-->
---
## プログラマがお祓い箱になるレベルで欲求されること
これらを満たせるなら良さそう
1. ネットにある情報を組み合わせて、欲しい物を作れるか
2. どの時点で正しい情報なのか判別がついているか
3. 言語やフレームワークにバグがある場合はそれを考慮するか
---
## これら全部を常に同時に満たすかどうか
1~3の条件を満たすプログラムの問題を何問か用意して、
思考実験させると良い。
<!--
で、自分が書いたスクリプトの中でこれらを満たすものがないかと思って、調べて見ました。で、ありました。
-->
{"slideOptions":"{\"controls\":false,\"slideNumber\":false,\"progress\":true}","description":":wave:","title":"cmdからのcsharpとPowershellへの移行とパフォーマンス","contributors":"[{\"id\":\"13bbf9e7-416d-4813-946c-591c31f51efc\",\"add\":27494,\"del\":1493}]"}