分類: Powershell

Powershell : Add/Remove Local User/Group

Powershell : Add/Remove Local User/Group

這裡介紹如何使用Powershell去新增/移除本機使用者/群組

下面是先設定手動輸入指定的密碼為變數$PWD,按下Enter後直接輸入密碼他會以****的方式來呈現,書完成按Enter即可。


1
$PWD = Read-Host -AsSecureString

再來就是新增使用者CW1TMS(登入帳號)
密碼使用變數$PWD,只要你Powershell視窗不關,你可以一直使用這個密碼。
設定顯示定名稱為CW1TMS。
設定描述為For CW1 UAT。


1
New-LocalUser "CW1TMS" -Password $PWD -FullName "CW1TMS" -Description "For CW1 UAT."

然後在圖形介面就會看到剛剛新增的使用者。

接著再來新增本機群組Test1,描述為Test1。


1
New-LocalGroup "Test1" -Description "Test1"

圖形介面同樣會看到。

再來是我要把CW1TMS這個剛剛新增的使用者加入Test1這個群組


1
Add-LocalGroupMember -Group "Test1" -Member "CW1TMS"

既然有新增就要有移除。
第一行是移除使用者CW1TMS。
第二航是移除群組Test1。


1
2
Remove-LocalUser "CW1TMS"
Remove-LocalGroup "Test1"

這是最基礎的,方便你搭配Script來做批次處理,您說是不是很方便呢!
下面有個範例,建立CW1TMS帳號,連同密碼不用手打(自動轉為SecureString)。
建立完帳號之後自動加入Administrators群組。


1
2
3
4
5
6
$USR = "CW1TMS"
$PWD = ConvertTo-SecureString "P@ssW0rd" -AsPlainText -Force
$FUN = "CW1 TMS"
$DSP = "CW1TMS Local User."
New-LocalUser $USR -Password $PWD -PasswordNeverExpires -FullName $FUN -Description $DSP
Add-LocalGroupMember -Group Administrators -Member $USR
Please follow and like us:
Use Powershell to detect Windows 10 version ( CBB/LTSC)

Use Powershell to detect Windows 10 version ( CBB/LTSC)

Windows 10 除了市面上看到的家用 / 專業 / 企業 / 教育之外,商務使用有另外區分為CBB/LTSB(C)。詳見https://docs.microsoft.com/zh-tw/windows/deployment/update/waas-overview

在這裡我想用Powershell判斷到底Windows 10是CBB / LTSB(C?),因為手上只有CBB和LTSB版的Windows 10 ,所以我也不能確定LTSC的結果是否雷同。


1
gwmi win32_operatingsystem

用Powershell跑完上面的指令會得到一些無用的概略資訊。但其實我只需要針對裡面OperatingSystemSKU這個值而已,所以在後面加參數。


1
gwmi win32_operatingsystem | Select OperatingSystemSKU

在這裡說明一下:CBB 版本會得到4,LTSB(C?)會得到125

但是,這種呈現方式,我很放到Powershell裡面轉成變數,所以還要加個參數


1
gwmi win32_operatingsystem | Select -ExpandProperty OperatingSystemSKU

這樣你就只會看到值,如此一來你就可很方便的放到你的Powershell Script去判斷Windows 10版本了,另外125這數值怎麼出來的我在官方文件一職沒找到

倒是其他各式各樣數值的有表可查如下方連結

https://docs.microsoft.com/zh-tw/windows/desktop/CIMWin32Prov/win32-operatingsystem

這裡有個小小的範例可以參考一下!


1
2
3
4
5
6
7
8
9
10
11
12
$SKU = gwmi win32_operatingsystem | Select -ExpandProperty OperatingSystemSKU
Switch ($SKU)
{
4
    {
    Write-Host Your OS is CBB
    }
125
    {
    Write-Host Your OS is LTSB
    }
}

以上感謝收看!

Please follow and like us:
Using Powershell list File in Folder – exclude subfolder

Using Powershell list File in Folder – exclude subfolder

檔案清單-排除特定子目錄。

用的是Get-ChildItem指令,搭配自訂function。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$rootFolderPath = 'D:\Docs'
$excludeDirectories = ("Test1","Script");

function Exclude-Directories
{
    process
    {
        $allowThrough = $true
        foreach ($directoryToExclude in $excludeDirectories)
        {
            $directoryText = "*" + $directoryToExclude
            $childText = "*" + $directoryToExclude + "\*"
            if (($_.FullName -Like $directoryText -And $_.PsIsContainer) `
                -Or $_.FullName -Like $childText)
            {
                $allowThrough = $false
                break
            }
        }
        if ($allowThrough)
        {
            return $_
        }
    }
}

Clear-Host

Get-ChildItem $rootFolderPath -Recurse | Exclude-Directories

如此一來要List File的時候,就可以排除特定子目錄了

Please follow and like us:
Powershell Execution Policy

Powershell Execution Policy

當已經習慣使用Powershell來管理或設定電腦時,很容易卡到Powershell腳本執行原則的設定。

Powershell有下面數種Policy可以設定
Unrestricted——-任何腳本皆可以執行,但是網路下載的會出現警示。
RemoteSigned—-本機撰寫的可以執行,網際網路下載來的需要經過簽署。
AllSigned———–只允許受信任的發行的腳本可以執行
Restricted———-關閉腳本執行功能。這是預設值
Default
Bypass
Undefined

下面的指令可以查看現在的Powershell執行原則


1
Get-ExecutionPolicy

下面的指令可以設定執行原則(需要管理員權限)


1
Set-ExecutionPolicy RemoteSigned

先說一下問題來源,因為Windows 預設就是關閉腳本執行預設值,所以你把Set-ExecutionPolicy RemoteSigned寫成Powershell腳本檔然後直接執行是行不通的。因為系統就不准你執行。同時,這一段指令也是必須要系統管理員權限才能執行。所以如果我今天是在一般使用者環境更可不能直接執行。另外Powershell也因為安全策略問題,所以他也不太能從Share Folder直接執行,大部分的情況下都會被拒絕。

先前一直沒有時間仔細去思考簡化這一段,導致每台電腦設定之前還要手打這一段指令,今天突然想到搭配Command批次檔來一起處理不能用一鍵設定好執行原則的問題。

這一個小小的設定一共需要3個檔案,1個bat檔、2個PS1檔案
我的情境是,三個檔案都放在網路分享資料夾上。

由Bat檔做導入,下面的批次會從Share Folder複製需要的PS1檔案到本機來,並且執行PSexec.ps1,執行完成之後再刪除檔案,不要留垃圾在User電腦


1
2
3
4
5
6
REM==========PSExec.bat====================
copy \\192.168.1.1\share\psexec.ps1 c:\tools /Y
copy \\192.168.1.1\share\psexec_sub.ps1 c:\tools /Y
powershell c:\tools\PSexec.ps1
del c:\tools\psexec.ps1 /F
del c:\tools\psexec_sub.ps1 /F

執行子層的PS1檔案PSExec_sub.ps1加上後面的參數
-Verb runas >> 這是為了讓powershell跳出提升權限的輸入帳號密碼的視窗
-Wait >> 這是要讓Powershell等候這一行執行完成關閉後才能繼續往下執行,
因為如果跑太快會回到前面的Bat檔案接續執行把需要的PS1檔案都刪掉。


1
2
#============PSExec.ps1=================
Start-Process powershell C:\tools\PSExec_sub.ps1 -Verb runas -Wait

再來才是核心重點,設定腳本執行權限


1
2
#============PSExec_sub.ps1==============
Set-ExecutionPolicy RemoteSigned

雖然只是一個很簡單的設定指令,但是由於微軟為安全性設下的重重關卡,所以只好靠點小技巧去簡化它,讓我可以用滑鼠雙擊就完成要打一串指令的麻煩。

======更新======
經過測試,在完全沒有手動執行過指令的,無法使用這個方式來變更Policy
第一次,至少必須用管理員執行Powershell,輸入


1
Set-ExecutionPolicy RemoteSigned

之後才能用script做調整設定。
如果還有找到新方式我會在此更新。

Please follow and like us:
經由指令方式使用相容模式來執行應用程式

經由指令方式使用相容模式來執行應用程式

這篇會出現的原因,是因為Skype v7 即將於2018/9/1終止支援。我們公司目前在Win7/10裝的都是Skype 7 Classic的版本。

誠如早先之前文章所說,公司使用Windows 10 2016 LTSB版本(無Microsoft Store),這版本正常來說要安裝在Windows 10是必須經由Microsoft Store來下載及安裝。

但是之前發現經由管理員帳號調整相容模式至Windows 8就能夠安裝了。所以我必須更動我的裝機批次。

研究之後,在盡可能減少人為操作之下,我必須在機碼裡面新增該執行的位置以及指定相容模式的參數。

這邊我說明一下,一般的方式都是在執行檔內容裡面修改相容性。如下圖

所以只要透過指令碼(Batch or PowerShell)把機把加進去即可

如果是全域使用者HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

如果是個別使用者HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers

 

所以我的方式是使用PowerShell加入機碼位於全域使用者。

New-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers” -Name “XXXXXXX\SkypeSetupFull.exe” -Value “WIN8RTM” -PropertyType “String” -Force

執行完安裝程式之後,不要在機碼留垃圾。刪除之

Remove-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers” -Name “XXXXXXX\Skype_All\SkypeSetupFull.exe”

這樣就可以順利達成我的目的地了

下面增列參數,相容系統模式

描述
Windows 8 WIN8RTM
Windows 7 WIN7RTM
Windows Vista SP2 VISTASP2
Windows Vista SP1 VISTASP1
Windows Vista VISTARTM
Windows XP SP3 WINXPSP3
Windows XP SP2 WINXPSP2
Windows 98 WIN98
Windows 95 WIN95

顯示設定

描述
8-bit (256) Color Mode 256COLOR
16-bit (65536) Color Mode 16BITCOLOR
640 x 480 Screen Resolution 640X480
Disable Display Scaling on High DPI Settings HIGHDPIAWARE

系統管理員執行

描述
Run Program as Administrator RUNASADMIN
Please follow and like us:
使用Powershell掃描軟體版本

使用Powershell掃描軟體版本

最近對於Powershell又有新發現了!

原由:

因為公司某個內部網站需要安裝元件,而且常常會更新,有時候會因為元件版本過於老舊或是未安裝元件而無法使用。

當然比較先進的方式是用Agent的方式做檢查並且派送,但是很無奈的在外商公司很多東西都不是Local IT可以觸碰的。

而且很詭異的是總部的派送常常會失敗,大概因為距離很遙遠吧(Cyberjaya or Pargue???)…

科技始終來自於惰性,我又不想一個一個打電話去問去檢查,這很不科學。

所以我一開始本來想用WMI的方式

1
<b>Get-WmiObject -Class Win32_Product</b>.

但是這會碰到兩個問題:

1.這效率非常不好,因為它會全部掃過一遍,他相對於資料庫查詢很像是 Select * from Win32_Product where (name like ‘XXXXX%’)。

2.根據我查到的資料,他會一併檢查軟體安裝的一致性,如果檢查到有問題還會一併觸發Windows Installer去做修復與重新設定。

原文說明:On Windows Server 2003, Windows Vista, and newer operating systems, querying Win32_Product will trigger Windows Installer to perform a consistency check to verify the health of the application. This consistency check could cause a repair installation to occur. You can confirm this by checking the Windows Application Event log.

參考1(新分頁):https://blogs.technet.microsoft.com/heyscriptingguy/2011/11/13/use-powershell-to-quickly-find-installed-software/

這樣的Script給User自己點選跑起來可能很久,還要擔心萬一發生其他想不到的問題。

後來發現了可以用掃描機碼的方式,

32位元:HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

64位元還要加上:HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

然後搭配Out-GridView這樣是不是淺顯易懂!

附上Powershell裡面的XXXXX請自由變化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function Search-RegistryUninstallKey {
param($SearchFor,[switch]$Wow6432Node)
$results = @()
$keys = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
foreach {
$obj = New-Object psobject
Add-Member -InputObject $obj -MemberType NoteProperty -Name GUID -Value $_.pschildname
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayName -Value $_.GetValue("DisplayName")
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayVersion -Value $_.GetValue("DisplayVersion")
if ($Wow6432Node)
{Add-Member -InputObject $obj -MemberType NoteProperty -Name Wow6432Node? -Value "No"}
$results += $obj
}

if ($Wow6432Node) {
$keys = Get-ChildItem HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall |
foreach {
$obj = New-Object psobject
Add-Member -InputObject $obj -MemberType NoteProperty -Name GUID -Value $_.pschildname
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayName -Value $_.GetValue("DisplayName")
Add-Member -InputObject $obj -MemberType NoteProperty -Name DisplayVersion -Value $_.GetValue("DisplayVersion")
Add-Member -InputObject $obj -MemberType NoteProperty -Name Wow6432Node? -Value "Yes"
$results += $obj
}
}
$results | sort DisplayName | where {$_.DisplayName -match $SearchFor}
}
[String]$OS = ((Get-CimInstance win32_OperatingSystem).version).split(".",2)[-2]
Switch($OS)
{
10
{
Search-RegistryUninstallkey -Wow6432Node -SearchFor "XXXXX" | Out-GridView -Wait
}
6
{
Search-RegistryUninstallkey -SearchFor "XXXXX" | Out-GridView -Wait
}
}

 

Please follow and like us:

Powershell偵測Java最新版本置換檔案

會有這支小程式這個起因是因為有個我覺得很神奇的廠商寫的程式,用了批次檔指定了Java.exe的執行路徑來跑某些程式功能。
其實如果Java版本都不會自動更新倒也沒甚麼困擾。
但是由於我們的總部常常會自動派送一些更新檔近來執行/安裝
以至於如果Java一被更新版本就會造成廠商寫的程式某部分功能失靈。
所以我的需求就是執行PS之後自動檢查Java裝在電腦的裡的最新版本,然後自動置換。
由於公司內存在兩種版本OS:Windows 7 x86和Windows 10 X64。
所以這也會造成Java安裝位置路徑不同。
偵測OS的部分,我用這一行程式碼

1
(Get-CimInstance win32_OperatingSystem).version)

然後其實我只需要取小數點最前位數
Windows 7是 6.X開頭的
Windows 10 是10.X開頭的

1
$OS = ((Get-CimInstance win32_OperatingSystem).version).split(".",2)[-2]

由於Windows 7偵測到版本會是6.3開頭,取得文字字串會是6,為了避免未來要置換的檔案命名困擾
我另外在判斷式裡面給了$OSver版本編號的變數。下面是Windows 10為例。

1
[String]$OSver = "10"

用下面這一行去讀取機碼裡面最新的Java版本

1
$javaver= dir "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment" | select -expa pschildname -Last 1

用下面這一行讀取JavaHome確認位置,純粹是讀出來之後顯示給User看的,沒有太多作用可有可無。

1
$Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\$Javaver" -Name JavaHome).JavaHome

告訴User目前OS版本、Java版本、Java路徑以及即將置換的Bat檔
當然這些批次檔要已經事先複製在本機或安排好放在某個Share Folder
例如:
AAA-7-1.8.0_141.bat
AAA-10-1.8.0_131.bat

1
2
3
4
Write-host "Your OperatingSystem is Windows 10 X64"
Write-Host "Your Java Version is $javaver"
Write-Host "Your Java path in $Javaexpath\bin"
Write-Host "Replace your PlugInHandler.bat with PlugInHandler-$OSver-$Javaver.bat."

正式置換檔案

1
Copy-Item -Path D:\ABC\DEF\UUU-$OSver-$Javaver.bat -Destination D:\ABC\DEF\UUU.bat -Force

其實這只是個很簡單的程式,是因為我的懶惰一直用滑鼠點很煩
下面是整段程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[String]$OS = ((Get-CimInstance win32_OperatingSystem).version).split(".",2)[-2]
[String]$Waitkey = "Press Enter to exit:::"
Switch($OS)
{
10
{
[String]$OSver = "10"
Write-host "Your OperatingSystem is Windows 10 X64"
$javaver= dir "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment" | select -expa pschildname -Last 1
$Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\WOW6432Node\JavaSoft\Java Runtime Environment\$Javaver" -Name JavaHome).JavaHome

}
6
{
[String]$OSver = "7"
Write-host "Your OperatingSystem is Windows 7 X86"
$javaver= dir "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment" | select -expa pschildname -Last 1
$Javaexpath = (Get-ItemProperty -path "HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\$Javaver" -Name JavaHome).JavaHome
}
}
Write-Host "Your Java Version is $javaver"
Write-Host "Your Java path in $Javaexpath\bin"
Write-Host "Replace your PlugInHandler.bat with PlugInHandler-$OSver-$Javaver.bat."
Copy-Item -Path D:\ABC\DEF\UUU-$OS-$Javaver.bat -Destination D:\ABC\DEF\UUU.bat -Force
Read-Host $Waitkey
Please follow and like us:

Powershell單行輸出不同顏色的文字

通常Powershell輸出文字都是用Write-Host。

想變換前景顏色加參數-ForegroundColor後面搭配顏色

想變換背景顏色加參數-BackgroundColor後面搭配顏色

例如:

1
Write-Host "Hello World" -ForegroundColor White -BackgroundColor Blue

這樣就會輸出藍底白字的Hello World

但是如果你想單行輸出不同顏色的字,就要另外自帶Function進來

分享一下我找到的Function:Write-Color

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Write-Color([String[]]$Text, [ConsoleColor[]]$Color = "White", [int]$StartTab = 0, [int] $LinesBefore = 0,[int] $LinesAfter = 0, [string] $LogFile = "", $TimeFormat = "yyyy-MM-dd HH:mm:ss") {
$DefaultColor = $Color[0]
if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host "`n" -NoNewline } } # Add empty line before
if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host "`t" -NoNewLine } } # Add TABS before text
if ($Color.Count -ge $Text.Count) {
for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
} else {
for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host $Text[$i] -ForegroundColor $DefaultColor -NoNewLine }
}
Write-Host
if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host "`n" } } # Add empty line after
if ($LogFile -ne "") {
$TextToFile = ""
for ($i = 0; $i -lt $Text.Length; $i++) {
$TextToFile += $Text[$i]
}
Write-Output "[$([datetime]::Now.ToString($TimeFormat))]$TextToFile" | Out-File $LogFile -Encoding unicode -Append
}
}

當你想輸出一行三個英文單字,但三個不同顏色,用-Text “AA”,”BB”,”CC” -Color 顏色,顏色,顏色

就可以將一行字分別輸出成三種顏色

1
Write-Color -Text "Blue ", "Green ", "White " -Color Blue,Green,White

另外她其他參數

-StartTab參數指的是在這一行前面增加你指定的TABS

-LinesBefore此排文字前,你想加幾行空白的行數

-LinesAfter此排文字後,你想加幾行空白的行數

你說這是不是很方便呢

Please follow and like us: