PowerShell 技能连载 - 正确地导入 Excel 的 CSV 文件
如果您导出一个 Excel 工作表到 CSV 文件中,并且希望将这个文件导入 PowerShell,以下是实现方法:
1 | $path = 'D:\sampledata.csv' |
重要的参数有 -UseCulture
(自动使用和 Excel 在您系统中所使用一致的分隔符)和 -Encoding Default
(只有使用此设置,所有特殊字符才能保持原样)。
如果您导出一个 Excel 工作表到 CSV 文件中,并且希望将这个文件导入 PowerShell,以下是实现方法:
1 | $path = 'D:\sampledata.csv' |
重要的参数有 -UseCulture
(自动使用和 Excel 在您系统中所使用一致的分隔符)和 -Encoding Default
(只有使用此设置,所有特殊字符才能保持原样)。
当一个 PowerShell 函数进行一个可能有风险的系统变更时,推荐使用 -WhatIf
和 -Configm
风险缓解参数。以下是基本的需求:
1 | function Test-WhatIf |
当运行这个函数时,PowerShell 会遵从 -WhatIf
和 -Confirm
参数设置:
1 | PS C:\> Test-WhatIf -WhatIf |
这个函数还定义了一个 ConfirmImpact
属性,它的值可以是 Low
、Medium
或 High
,表示这个函数的操作引起的改变有多严重。
当 ConfirmImpact
的值大于或等于 $ConfirmPreference
变量中定义的值时,PowerShell 自动向用户显示一个确认信息:
1 | PS C:\> $ConfirmPreference = "Low" |
PowerShell 可以根据数据类型匹配自动地绑定参数。以下是一个体现该特性的示例
1 | function Test-Binding |
现在用户可以测试 Test-Binding
并且提交参数:
1 | PS C:\> Test-Binding "Hello" |
在前一个技能中我们解释了如何在所有可用的范围内设置环境变量的方法。但是如何移除环境变量呢?
巧合地,您可以用完全相同的方法做这件事情,只需要将一个空字符串赋给该变量。然而,前一个技能中的函数中的 -VariableValue
参数不能接受空字符串:
1 | function Set-EnvironmentVariable |
当您尝试着赋值空字符串时,将会收到这样的提示:
1 | PS C:\> Set-EnvironmentVariable -VariableName test -VariableValue "" -Target User |
这是因为当您将一个参数声明为 “Mandatory”,PowerShell 缺省情况下将拒绝空字符串和 null 值。
您可以将 VariableValue
参数设为可选的,但是这样当您调用该函数不传该参数时,PowerShell 将不再提示。如何使一个必选参数能接受 null 和空字符串呢?
只要稍微改一下,加上 [AllowNull()]
和/或 [AllowEmptyString()]
以上函数就可以支持删除环境变量:
1 | function Set-EnvironmentVariable |
以下是删除 “Test” 环境变量的方法:
1 | PS C:\> Set-EnvironmentVariable -VariableName test -VariableValue "" -Target User |
有些时候您会见到一些脚本使用 Select-Object
向现有的对象附加信息,类似以下代码:
1 | Get-Process | |
它可以工作,但是 Select-Object
创建了一个完整的对象拷贝,所以这种方法速度很慢而且改变了对象的类型。您可能注意到了 PowerShell 不再使用正常的表格方式输出进程对象,也是因为这个原因。
如果您想设置环境变量,env:
驱动器只能修改进程级别的环境变量。要设置用户或者机器级别的环境变量,请试试这个函数:
1 | function Set-EnvironmentVariable |
请注意 $Target
变量如何使用特殊的数据类型 “EnvironmentVariableTarget” ,当您在 PowerShell ISE 或其它带有 IntelliSense 功能的编辑器中,-Target
参数的可选项有 “Process”、”User” 和 “Machine”。
以下是如何在用户级别创建名为 “Test”,值为 12 的环境变量的方法:
1 | PS C:\> Set-EnvironmentVariable -VariableName test -VariableValue 12 -Target User |
PowerShell 5 带来了新的将文本复制到剪贴板,以及取出剪贴板文本的 cmdlet:Set-Clipboard
和 Get-Clipboard
。
Set-Clipboard
也支持 -Append
参数,它可以向剪贴板尾部附加文本。这可以成为一种新奇且有用的记录脚本行为的方法:
1 | Set-ClipBoard "Starting at $(Get-Date)" |
这个脚本片段使用 Set-Clipboard
将信息粘贴至剪贴板中。脚本运行后,您可以将剪贴板内容粘贴至剪贴板来查看脚本输出的日志。
当一个用户登录计算机时,将创建一套用户配置文件。在前一个技能中我们介绍了如何用 PowerShell 转储计算机中的用户配置文件列表。
如果您想删除一个用户账户,PowerShell 可以帮您清除。以下是使用方法:
首先,调整 $domain
和 $username
变量指向您想删除的用户配置文件。然后,在 PowerShell 中以管理员特权运行以下代码:
1 | #requires -RunAsAdministrator |
第一部分将用户名转换为 SID 并且用它来指定用户配置文件。WMI 的 Delete()
方法删除所有用户配置文件。注意:您将丢失删除的用户配置文件中的所有数据。
要转储一台机子上用户配置文件的原始列表,请使用这行代码:
1 | Get-CimInstance -Class Win32_UserProfile | Out-GridView |
您将会获得所有用户配置文件的所有详细信息。用户名可以在 SID 属性中找到,但它是以 SID 的格式表示。要获得真实的用户名,需要将 SID 转换。这段代码创建一个以真实用户名为字段名的哈希表:
1 | $userProfiles = Get-CimInstance -Class Win32_UserProfile | |
现在可以轻松地转储机器上所有带用户配置文件的用户列表了:
1 | PS C:\> $userProfiles.Keys | Sort-Object |
要获取某个用户配置文件的详细信息,请访问哈希表的字段:
1 | PS C:\> $userProfiles["MYDOMAIN\User01"] |
假设您已经启用了 PowerShell 远程处理(请看我们之前的技能),那么您可以同时在多台计算机上运行命令。
以下例子演示了这个操作,并且在列表中所有计算机中所有用户的桌面上放置一个文件。警告:这是个很强大的脚本。它将在列表中的所有机器上运行 $code
中的任何代码,假设启用了远程处理,并且您有相应的权限:
1 | # list of computers to connect to |
例如,如果您将 $code
中的代码替换为 Stop-Computer -Force
,所有机器将会被关闭。
当您在目标机器上启用了 PowerShell 远程处理,请试试交互式地连接它。以下是您值得尝试的例子。只需要确保将 targetComputerName
替换成您需要连接的目标机器名即可:
1 | PS C:\> Enter-PSSession -ComputerName targetComputerName |
如果连接失败并且报 “Access Denied” 错误,您可能需要使用 -Credential
参数并且使用一个不同的用户账户来登录远程计算机。您可能需要本地管理员特权。
如果连接失败并且报告 RDP 错误,或者如果 WinRM 无法找到目标计算机名,请使用 Test-WSMan
检查连接。如果这无法连接上,请重新检查远程设置。您可能需要像之前的技能中描述的那样,先在目标机器上运行 Enable-PSRemoting
。
请不要运行会打开窗口的命令。只能运行产生文本信息的命令。
要离开远程会话,请使用 exit
命令。