There are several ways:
Write-Host: Write directly to the console, not included in function/cmdlet output. Allows foreground and background colour to be set.
Write-Debug: Write directly to the console, if $DebugPreference set to Continue or Stop.
Write-Verbose: Write directly to the console, if $VerbosePreference set to Continue or Stop.
The latter is intended for extra optional information, Write-Debug for debugging (so would seem to fit in this case).
Additional: In PSH2 (at least) scripts using cmdlet binding will automatically get the -Verbose and -Debug switch parameters, locally enabling Write-Verbose and Write-Debug (i.e. overriding the preference variables) as compiled cmdlets and providers do.
或着打开系统上内置的应用程序 “CharacterMap” 来选择一个你想在控制台上显示的的符号。下面的例子就是通过这种途径来把PowerShell控制台上的提示符信息变得更加诡异:
function prompt
{
$specialChar1 = [Char]0x25ba
Write-Host 'PS ' -NoNewline
Write-Host $specialChar1 -ForegroundColor Green -NoNewline
' '
$host.UI.RawUI.WindowTitle = Get-Location
}
http://www.pstips.net/using-symbols-in-console-output.html
Powershell处理函数的参数 4
Powershell处理函数的参数 4
Powershell函数可以接受参数,并对参数进行处理。函数的参数有3个特性:
- 任意参数:内部变量$args 接受函数调用时接受的参数,$args是一个数组类型。
- 命名参数:函数的每一个参数可以分配一个名称,在调用时通过名称指定对应的参数。
- 预定义参数:函数在定义参数时可以指定默认值,如果调用时没有专门指定参数的值,就会保持默认值。
$args 万能参数
给一个函数定义参数最简单的是使用$args这个内置的参数。它可以识别任意个参数。尤其适用哪些参数可有可无的函数。
1
2
3
4
5
6
7
8
9
10
11
|
function
sayHello
{
if
(
$args
.Count
-eq
0)
{
"No argument!"
}
else
{
$args
|
foreach
{
"Hello,$($_)"
}
}
}
|
无参数调用时:
1
2
|
PS C:Powershell> sayHello
No argument!
|
一个参数调用:
1
2
|
PS C:Powershell> sayHello LiLi
Hello,LiLi
|
多个参数调用时:
1
2
3
4
|
PS C:Powershell> sayHello LiLi Lucy Tom
Hello,LiLi
Hello,Lucy
Hello,Tom
|
因为$arg是一个数组,可以用它求和。
1
2
3
4
5
6
7
8
|
function
Add
{
$sum
=0
$args
|
foreach
{
$sum
=
$sum
+
$_
}
$sum
}
Add 10 7 3 100
#120
|
设置参数名称
1
2
3
4
5
6
7
8
9
|
function
StringContact(
$str1
,
$str2
)
{
return
$str1
+
$str2
}
StringContact moss fly
StringContact
-str1
word
-str2
press
mossfly
wordpress
|
给参数定义默认值
1
2
3
4
5
6
|
function
stringContact(
$str1
=
"moss"
,
$str2
=
"fly"
)
{
return
$str1
+
$str2
}
stringContact Good Luck
stringContact
|
使用强类型参数
通过之前的例子发现将用户的参数传递给函数显得比较混乱。罪魁祸首就是Powershell的参数解释器,它可以自动处理和分配参数给函数。
函数的参数解释器比较傲慢,它对你提供的参数的信息完全不关心。它只会粗略地将参数进行分割,并且最大限度的进行自动类型转换。事实上,这种类型转换很多时候并不完美。所以最好提前能够对参数进行强类型限制。
限制数字类型
1
2
3
4
5
|
function
subtract(
[int]
$value1
,
[int]
$value2
)
{
return
$value1
-
$value2
}
subtract moss fly
|
上面的函数执行后,会抛出异常:
subtract : 无法处理对参数“value1”的参数转换。无法将值“moss”转换为类型“System.Int32”。错误:“输入字符串的格式不正确。”
因为subtract参数定义了强类型,参数的类型可能引起函数的处理结果。例如调用上面的函数
subtract 8.1 7.9
结果为0
但是如果将上面的函数的参数定义为Double型,
1
2
3
4
5
6
|
function
subtract(
[double]
$value1
,
[double]
$value2
)
{
return
$value1
-
$value2
}
subtract 8.1 7.9
#输出 0.199999999999999
|
限制日期类型
函数的参数解释器会自动尝试将字符串转换成日期类型,如果转换失败就是抛出异常。
1
2
3
4
5
6
7
8
|
function
DayOfWeek(
[datetime]
$date
)
{
return
$date
.DayOfWeek
}
DayofWeek
'1927-8-1'
#Monday
DayofWeek 2008-8-1
#Friday
|
DayOfWeek : 无法处理对参数“date”的参数转换。无法将值“someday”转换为类型“System.DateTime”。错误:“该字符串未被识别为有效的 DateTime。有一个从索引 0 处开始的未知字。”
DayofWeek someday
Switch 参数
Powershell函数最简单的参数类型为布尔类型,除了使用Bool类型,也可以使用Switch关键字。
下面的函数逆转字符串,但是可以通过$try 参数进行控制,如果没有指定$try的值,默认值为$false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function
tryReverse(
[switch]
$try
,
[string]
$source
)
{
[string]
$target
=""
if
(
$try
)
{
for
(
[int]
$i
=
$source
.length -1;
$i
-ge
0 ;
$i
--)
{
$target
+=
$source
[
$i
]
}
return
$target
}
return
$source
}
tryReverse
-source
www.mossfly.com
tryReverse
-try
$true
-source
www.mossfly.com
# www.mossfly.com
# moc.ylfssom.www
|
获取文件的前N行,这也是一个有趣的事。可以用一句PowerShell来搞定。举例如下:
复制代码 代码如下:
Get-Content d:\1.txt -totalcount 100 | set-Content top100.txt
说明:这里的Set-Content top100.txt是把前面一个语句的结果,写一个新的文件——top100.txt
如果这个时候,你想获取文件的第100行,你会不会想到去做一个很复杂的循环?如果是,那说明你有很好的编程素养。但是PowerShell告诉你不用如此麻烦。举例如下:
复制代码 代码如下:
(Get-Content d:\1.txt -TotalCount 100)[-1]
说明:啥!你看到了啥?!如果你简单的看()[-1],那是不是像数组呢?-1表示最后一个数组元素,那就表示前100行的最后一行,那是不是第100行呢?!
最后要说一下,这个命令返回的是一个对象数组,可以用ForEach-Object(别名是%)去遍历它。非常方便,前面你应该已经看到“太阳”的例子了!
-----------------------注意,读取只有一行的文本,会将行作为单个字符串------------------
(PowerShell) 文件操作
- Get current ps1 file's parent path
$x = Split-Path -Parent $MyInvocation.MyCommand.Definition
- Create a folder if it does not exist.
$myNewFolder = $x +"myTestFolder\" if(!(Test-Path $myNewFolder)) { new-item -path $x -name myTestFolder -type directory }
- Open a XML file , and get what we want.
[String]$xmlDocPath = "F:/TestData/TestXml.xml" [String]$nodeName = "Property" $xmlDoc = New-Object "System.Xml.XmlDocument" $xmlDoc.Load($xmlDocPath) $nodelist = $xmlDoc.GetElementsByTagName($nodeName); foreach($node in $nodelist) { # Use Attributes will throw error. #$namestr = $node.Attributes[0].InnerXml #Write-Host "$namestr" $namestr = $node.GetAttribute("Value") Write-Host "$namestr" $childnodes= $node.ChildNodes; foreach($childnode in $childnodes ) { $textstr = $childnode.InnerXml.ToString() Write-Host "$textstr" } }
Xml file
<?xml version="1.0" encoding="gb2312"?> <Root> <Property Name = "First" Value ="value"> <GUID>xxoxx</GUID> <Tel>123456</Tel> <Start>5.95</Start> </Property> <Property Name = "Second"> <GUID>xxoxx</GUID> <Tel>123456</Tel> <Start>5.95</Start>a </Property> </Root>
- Get special file from a directory , and copy them into local folder
$fileName = "test123" $fileList = Get-ChildItem -path $LogServer -Filter "$fileName*" foreach($file in $fileList) { source = $LogServer+$file Copy-Item $source $targetFolder Write-Host "$file"."is copied. " }
获取指定文件夹下的所有文件夹大小
$rootDirectory = "D:\TFS" $colItems = (Get-ChildItem $rootDirectory | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object) foreach ($i in $colItems) { $subFolderItems = (Get-ChildItem $i.FullName -recurse | Measure-Object -property length -sum) $i.FullName + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB" }