[TOC]

3.运行脚本

描述: 脚本和批处理都属于伪可执行文件,它们只是包含了若干命令行解释器能够解释和执行的命令行代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.执行批处理文件:批处理是扩展名为”.bat”的文本文件,它可以包含任何cmd控制台能够处理的命令
PS C:\PS> ./ping #实际执行ping.bat
batch File Test
Press any key to continue . . .
Volume in drive C has no label.
Volume Serial Number is 4E9B-D846


# 2.执行VB脚本文件,执行.\test.vbs 会遍历当前Win32进程,并把每个进程的详细信息通过窗口显示出来。
Set wmi = GetObject("winmgmts:")
Set collection = wmi.ExecQuery("select * from Win32_Process")
For Each process in collection
WScript.Echo process.getObjectText_
Next

PS C:\PS> cscript.exe .test.vbs #PS执行VB脚本


# 3.执行powershell脚本扩展名为“.ps1”
PS C:\PS> echo "dir;Get-PSProvider;help dir" >test.ps1
PS C:\PS> Get-Content ./test.ps1
dir;Get-PSProvider;help dir
PS C:\PS> ./test.ps1

注意事项:

  • 初次执行PS1脚本时可能会碰到一个异常,由于默认安全设置禁用了执行脚本,要启用这个功能需要拥有管理员的权限。

$C = Get-Culture | Select-Object -Property *

@{TestKey = (‘x’ * 200)} | Out-String -Width 250

PS C:\Users\WeiyiGeek> Get-Command -Name *Printer

CommandType Name Version Source


Function Add-Printer 1.1 PrintManagement
Function Get-Printer 1.1 PrintManagement
Function Remove-Printer 1.1 PrintManagement
Function Rename-Printer 1.1 PrintManagement
Function Set-Printer 1.1 PrintManagement
Cmdlet Out-Printer 3.1.0.0 Microsoft.PowerShell.Utility

选择对象的属性

包含在每一个对象中的属性可能有很多,但是并不是所有的属性你都感兴趣,这时可以使用Select-Object 限制对象的属性。接下来的例子演示如果获取机器上匿名帐号的完整信息。

PS C:Usersv-bali.FAREAST> Get-WmiObject Win32_UserAccount -filter “LocalAccount=True AND Name=’guest’”

AccountType : 512
Caption : myhomeguest
Domain : myhome
SID : S-1-5-21-3064017030-3269374297-2491181182-501
FullName :
Name : guest

如果你只对用户名、描述,启用感兴趣。

PS C:Powershell> Get-WmiObject Win32_UserAccount -filter “LocalAccount=True AND
Name=’guest’” | Select-Object Name,Description,Disabled

Name Description Disabled


guest Built-in account for gu… True

#使用比较运算符”like”过滤当前应用的数组, 这里可以用比较运算符结合控制台命令匹配出所有条件。
@(ipconfig /all) -like “IPV4
pageid: 327
IPv4 地址 . . . . . . . . . . . . : 192.168.1.88(首选)

形用户界面
Cmdlet

Out-GridView

Show-Command

Show-ControlPanelItem

Show-EventLog

参数

PS编程之命令行参数传递与绑定:

  • 方法1:$args 参数位置传值法它实际是一个对象数组,注意输入参数的位置是固定的并且$args[0]表示命令中输入的第一个参数并非脚本名称(与Bash Shell有区别)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # args.ps1 文件内容
    Write-Host $args[0]
    Write-Host $args[1]
    Write-Host $args[2]
    Write-Host "命令行:$args" #注意在""之中 $args[0] 加入没有任何意义,它只会解析$args 数组;
    Write-Host -noNewLine "命令行:" $args[0] $args[1] $args[2]

    #执行
    $args.ps1 1 "参数2" param3

    #执行结果
    1
    参数2
    param3
    命令行:1 参数2 param3
    命令行:1 参数2 param3
  • 方法2:CmdletBinding 脚本内部变量名,适合于传递多个参数值可以指定参数名称,并且参数值的位置随机。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # DeployBuildEnv.ps1 文件内容
    [CmdletBinding()]
    Param (
    [string] $Name = "",
    [Int32] $Age = 0,
    [string] $Gender = "未知"
    )

    $arg = $Name + " - " + $age + " - " + $Gender;
    Write-Host $arg
    Write-Host "命令行绑定: $arg"


    #执行
    .\DeployBuildEnv.ps1 -Name WeiyiGeek -Age 20 -Gender 男

    #执行结果
    WeiyiGeek - 20 - 男
    命令行绑定: WeiyiGeek - 20 - 男

注意事项:

  • #必须放在脚本最上面否则报错CmdletBinding
  • PS命令行支持:单引号,双引号,中文的单引号,中文的双引号 ,以及中文变量名,中文参数名(linux版的powershell也完全支持)。

模块查找与安装:
Tips:没有该find-module模块的点击,注意需要以管理员权限运行;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 模块查找
find-module *ssh*
# Version Name Repository Description
# ------- ---- ---------- -----------
# 2.2 Posh-SSH PSGallery Provide SSH and SCP functionality for executing commands against remote hosts.
# 0.0.3 dockeraccesshelper PSGallery Allow a user account to access the docker engine without elevated access rights

# 安装Posh-SSH的模块
Install-Module Posh-SSH
# 你正在从不受信任的存储库安装模块。如果你信任该存储库,请通过运行 Set-PSRepository cmdlet 更改其 InstallationPolicy
# 值。是否确实要从“PSGallery”安装模块?
[Y] 是(Y) [A] 全是(A) [N] 否(N) [L] 全否(L) [S] 暂停(S) [?] 帮助 (默认值为“N”): y

# 删除模块
# 删除Posh-SSH的目录:C:\Program Files\WindowsPowerShell\Modules\Posh-SSH
remove-module -name posh-ssh -Force -Verbose -Debug

#查看模块命令
get-command -Module posh-ssh

在PowerShell中如何检测模块是否存在

我们可以使用Get-Module的另一个参数-ListAvailable来列出是否含有潜在的模块。
Get-Module -ListAvailable -Name Azure

Powershell检测网络中存活地址

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
# 方式1 
for($i=1; $i -le 255; $i++){
ping -n 3 10.0.0.$i >> Paddr.txt
}

# 方式2
$Ping = New-Object system.net.networkinformation.ping
1..253 | % { $Ping.send( "192.168.12.$_" ) | select address,status} | Out-File -FilePath IPaddr.txt -Encoding utf8
$IP = Get-Content "IPaddr.txt" | Where-Object { $_ -match "Success" }
-split $IP | Where-Object { $_ -like "192*" } | Out-File -FilePath IP-Successful.txt -Encoding utf8



$hostname = foreach ( $i in $IPS ) { [System.Net.DNS]::GetHostByAddress($i).HostName;$i}
$hostname


[System.Net.DNS]::GetHostName()

[System.Net.DNS]::GetHostAddresses("192.168.12.188")

188..199 | % { [System.Net.DNS]::GetHostEntry("192.168.12.194").HostName; }
188..199 | % { [System.Net.DNS]::GetHostEntry("192.168.12.$_").HostName; }
HostName Aliases AddressList
-------- ------- -----------
USER-MVFI1L2V69 {} {fe80::5936:33a7:29bf:7d6e%5, 192.168.12.188}

https://docs.microsoft.com/zh-cn/dotnet/api/system.net.dns?view=netcore-3.1

下面再附带两个循环读取一个文件夹下的所有子文件夹下的、所有的文件个数的代码:

Get-ChildItem -Path $env:windir -Force -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.PSIsContainer -eq $false } |
Measure-Object |
Select-Object -ExpandProperty Count

[System.IO.Directory]::GetFiles(“F:\gzkz-2020\new”, “*”, “AllDirectories”).Count

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
param
(
[Parameter(Mandatory=$true)][string]$DnsName,
[Parameter(Mandatory=$true)][string]$UserName,
[string]$RoleName=$null,
[string]$InstanceName=$null,
[switch]$ManagementServer,
[switch]$Agent
}

$PDF_DIR="C:\Users\WeiyiGeek\Desktop\123\2021年10月自考答案pdf"
# PDF 批量更名
function PDF_copy() {
Write-Output "# 正在更名 ${PDF_DIR} 目录中的PDF文件到..\rename目录中...."
foreach ( $pdf in (Get-ChildItem "${PDF_DIR}" -Filter *.PDF).Name ){
$sub = $pdf.Substring(5,5)+".pdf"
Write-Host "$pdf -> $sub" -ForegroundColor Green
Copy-Item -Path "${PDF_DIR}\${pdf}" -Destination "..\rename\${sub}" -Recurse -Force
}
}


# PDF 批量打印
$PDF_DIR="C:\Users\WeiyiGeek\Desktop\123\123"
function PDF_print(){
Write-Output "# 正在打印 ${PDF_DIR} 目录中的PDF文件...."
foreach ( $pdf in (Get-ChildItem "${PDF_DIR}" -Filter *.PDF).FullName )
{
Write-Output "${pdf}"
Start-Process -FilePath "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" -ArgumentList "/h /p ${pdf}"
}
}


PDF_print
PDF_copy


$SRCDIR="\\10.10.108.250\PhotoShare\ZK202104\dtk\pic\"
$YX="cs","cy","gs","jt","kj","lg","wl","xn","xz"
foreach ( $xx in $YX) {
$diskname = (get-Volume -FileSystemLabel $xx).DriveLetter
$srcyx = "${SRCDIR}${xx}"
echo $srcyx - "${diskname}:\"
Copy-Item -Path "$srcyx" -Destination "${diskname}:/" -Force -Recurse
}

$SRCDIR="\\10.10.108.250\PhotoShare\ZK202104\zkyx\"
$YX="cs","cy","gs","jt","kj","lg","wl","xn","xz"
foreach ( $xx in $YX) {
$diskname = (get-Volume -FileSystemLabel $xx).DriveLetter
$srcyx = "${SRCDIR}${xx}\*"
echo "$srcyx - ${diskname}:\"
Copy-Item -Path "$srcyx" -Destination "${diskname}:/" -Force -Recurse
}
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
PS C:/Documents and Settings/Administrator> ./Convert-Image.ps1 -inFile 01.jpg

GAC Version Location
--- ------- --------
True v2.0.50727 C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll

LastWriteTime : 2008-7-25 22:05:36
Length : 135580
Name : 01.gif



代码如下:

# Convert one graphic image to another

param ( $inFile, $type = "gif", $outFile, [switch]$force )

[reflection.assembly]::LoadWithPartialName("System.drawing")

#

# First check to see if our input file exists

$iFile = (resolve-path $inFile -ea silentlycontinue ).path

if ( ! $iFile ) { "File '$inFile' not found, exiting" ; exit }

# now check to see if the output file exists, if force

# we will continue, otherwise we exit

if ( ! $outFile )

{

$tFile = get-item (resolve-path $inFile)

$outFile = $tFile.Fullname -replace ($tFile.Extension + "`$"),".$type"

}

if ( (test-path $outFile) -and (! $force) ) { "File '$outFile' exists, exiting"; exit }

# make sure we have an encoder before changing anything on

# the filesystem

$codecs = [drawing.imaging.ImageCodecInfo]::GetImageEncoders() |

foreach { $h = @{} } { $h.($_.formatdescription) = $_ } { $h }

$encoder = $codecs.$type

if ( ! $encoder )

{

"No encoder of type '$type', exiting";

"Available encodings are: " + [string]::Join(", ", $h.keys)

exit

}

# This hoop is needed because resolve-path needs

# the file to actually exist. We shouldn't get here

# unless the file doesn't exist, or we're going to remove it

# by force.

if ( test-path $outFile ) { remove-item $outFile }

[void](new-item -type file $outFile)

$outFile = (resolve-path $outFile).path

remove-item $outFile

# read the image

$image = [system.drawing.image]::FromFile($iFile)

$image.Save($outFile, $encoder.FormatId)

$image.Dispose()

# Get the file we just created

get-item $outFile


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$gifs=dir -Path "C:\Users\WeiyiGeek\Documents\Tencent Files\291238737\FileRecv\GIF" -Filter '*.gif';
$newPath=$gifs[0].DirectoryName+'\JPG';
if(-not (Test-Path $newPath)){mkdir $newPath|Out-Null;};
if($gifs){
foreach($g in $gifs){
$bf=[System.Drawing.Bitmap]::FromFile($g.fullName);
$newFileName=$newPath+'\'+$g.BaseName+'.jpg';
$bf.Save($newFileName,[System.Drawing.Imaging.ImageFormat]::Jpeg);
$bf.Dispose();
}
Write-Host ('共'+$gifs.Count+'个,转换完成...');
}else{
Write-Host '当前目录没有找到任何GIF文件!';
}

# 另存为转换GIF到PNG-递归.bat文件,放在某个目录下,双击运行即可。会自动查找子目录中,转换后存于每个子目录的PNG目录中。

powershell.exe -command "$path=(Get-Location).Path;$gifs=dir -Path $path -Filter '*.gif' -Recurse;if($gifs){foreach($g in $gifs){$bf=[System.Drawing.Bitmap]::FromFile($g.fullName);$newPath=$g.DirectoryName+'\PNG';if(-not (Test-Path $newPath)){mkdir $newPath|Out-Null;};$newFileName=$newPath+'\'+$g.BaseName+'.png';$bf.Save($newFileName,[System.Drawing.Imaging.ImageFormat]::Png);$bf.Dispose();}Write-Host ('共'+$gifs.Count+'个,转换完成...');}else{Write-Host '当前目录没有找到任何GIF文件!';};"

类库探源——System.Drawing.Bitmap
https://www.cnblogs.com/Aphasia/p/4158827.html

http://www.colorconsole.de/PS_Windows/de/Get-Counter.htm

Get-Counter

该函数下可以把现有的电脑监控统计数据 直接提取出来 ,