PowerShell 技能连载 - 刷新新挂载的磁盘
如果您的脚本刚刚挂载了一个新的驱动器,PowerShell 可能无法立即存取它(例如通过 Get-ChildItem
),因为 Powerell 尚未更新它的驱动器列表。
要更新 PowerShell 驱动器列表,请用这行代码:
$null = Get-PSDrive
如果您的脚本刚刚挂载了一个新的驱动器,PowerShell 可能无法立即存取它(例如通过 Get-ChildItem
),因为 Powerell 尚未更新它的驱动器列表。
要更新 PowerShell 驱动器列表,请用这行代码:
$null = Get-PSDrive
近期多数 cmdlet 都是包装在模块中。模块是从 PowerShell 2.0 开始引入的概念。它们的主要好处是可以复制粘贴部署(不需要安装)以及模块自动加载(当您需要时,PowerShell 将自动加载模块)。
有一些 cmdlet 还是用 PowerShell snap-in (PSSnapin) 的方式包装,而不是采用模块的方式包装。PSSnapin 是从 PowerShell 1.0 就开始引入的。PSSnapin 需要安装才能使用。而且由于它们是注册在 HKEY_LOCAL_MACHINE
中,所以它们安装时往往需要管理员权限。
要列出所有可用的 PSSnapin,请运行这行代码:
Get-PSSnapin -Registered
与模块相对,PSSnapin 需要先手动加载,才能使用其中的 cmdlet。这行代码将会加载所有可用的 PSSnapin:
Get-PSSnapin -Registered | Add-PSSnapin -Verbose
所有的 cmdlet 都位于模块或是 snap-in 中。要查看当前加载了哪些模块,请使用 Get-Module
命令。
在 PowerShell 3.0 或更高版本中,当您运行多数模块中的 cmdlet 时,它们都将被隐式地导入。这种聪明的机制实现了“按需加载”的效果,所以在多数情况下不需要手动加载模块,或是显式地手动加载所有模块。
要关闭自动加载,请使用这行代码:
$PSModuleAutoLoadingPreference = 'none'
请注意当您这么做的时候,您有责任加载所有需要的模块。
如果您希望加载所有可用的模块,请使用 Import-Module
命令。
这将读取您整个系统中所有可用的模块:
Get-Module -ListAvailable | Import-Module -Verbose
Get-Command
是当您需要查找某个命令来完成一件事情时的主要工具。
您可以这样搜索动词和/或名词:
# find all cmdlets/functions that stop things
Get-Command -Verb Stop
# find all cmdlets/functions that affect services
Get-Command -Noun Service
从 PowerShell 3.0 开始,Get-Command
还可以根据一个给定的参数查找 cmdlet 或函数:
# new in PS3 and better
# find all cmdlets/functions with a -ComputerName parameter
Get-Command -ParameterName ComputerName
请注意 Get-Command
是在已加载的 cmdlet/函数中搜索。请确保在搜索前已导入了所需的模块。
通过一行 WMI 代码,就可以查看您的 CPU 详情:
PS> Get-WmiObject -Class Win32_Processor | Select-Object -Property Name, Number*
Name NumberOfCores NumberOfLogicalProcessors
---- ------------- -------------------------
Intel(R) Core(TM) i7-26... 2 4
在服务器中,Powershell 可以通过 Install-WindowsFeature
命令安装 Windows 功能。
若您将 Install-WindowsFeature
返回的结果保存下来,则可以用 Get-WindowsFeature
查看安装的状态:
# install features on server and save result in $result
Install-WindowsFeature -Name AD-Domain-Services, DNS -IncludeManagementTools -OutVariable result -Verbose
# view the result of your change
Get-WindowsFeature -Name $result.FeatureResult.Name
脚本块是一段可执行的 PowerShell 代码。您通常可以将语句包裹在大括号中创建脚本块。
若要在脚本中动态创建脚本块,以下是将一个字符串转换为脚本块的方法。
$scriptblock = [ScriptBlock]::Create('notepad')
通过这种方法,您的代码首先以字符串的形式创建代码,然后将字符串转换为脚本块,然后将脚本块传递给您需要的 cmdlet(例如 Invoke-Command
):
PS> Invoke-Command -ScriptBlock 'notepad'
Cannot convert the "notepad" value of type "System.String" to type
"System.Management.Automation.ScriptBlock". (raised by: Invoke-Command)
PS> Invoke-Command -ScriptBlock ([ScriptBlock]::Create('notepad'))
缺省情况下,文件和文件夹从它们的父节点继承权限。要停用继承,并且只保留显式权限,请做以下两件事情:增加你需要显式权限,然后禁止继承。
这个示例代码创建了一个名为“_PermissionNoInheritance_”的文件夹,然后为当前用户赋予读权限,为管理员组赋予完整权限,并且禁止继承。
# create folder
$Path = 'c:\PermissionNoInheritance'
$null = New-Item -Path $Path -ItemType Directory -ErrorAction SilentlyContinue
# get current permissions
$acl = Get-Acl -Path $path
# add a new permission for current user
$permission = $env:username, 'Read,Modify', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission
$acl.SetAccessRule($rule)
# add a new permission for Administrators
$permission = 'Administrators', 'FullControl', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission
$acl.SetAccessRule($rule)
# disable inheritance
$acl.SetAccessRuleProtection($true, $false)
# set new permissions
$acl | Set-Acl -Path $path
在前一个例子中,我们演示了如何向已有的文件夹添加新的 NTFS 权限。如果您希望重置权限并且移除所有之前所有非继承的 NTFS 权限,以下是示例代码:
# make sure this folder exists
$Path = 'c:\sampleFolderNTFS'
# get explicit permissions
$acl = Get-Acl -Path $path
$acl.Access |
Where-Object { $_.isInherited -eq $false } |
# ...and remove them
ForEach-Object { $acl.RemoveAccessRuleAll($_) }
# set new permissions
$acl | Set-Acl -Path $path
要查看某个文件或者文件夹被直接赋予了哪些 NTFS 权限,请注意“isInherited”属性。这段代码将创建一个名为“_sampleFolderNTFS_”的新文件夹,并且列出所有非继承的 NTFS 权限。当您创建该文件夹时,它只拥有继承的权限,所以您查看非继承权限的时候获得不到任何结果:
$Path = 'c:\sampleFolderNTFS'
# create new folder
$null = New-Item -Path $Path -ItemType Directory -ErrorAction SilentlyContinue
# get permissions
$acl = Get-Acl -Path $path
$acl.Access |
Where-Object { $_.isInherited -eq $false }
当您增加了非继承权限时,这段代码将会产生结果。这是通过 PowerShell 增加非继承权限的方法。它将针对当前用户添加读、写、修改权限:
$acl = Get-Acl -Path $path
# add a new permission
$permission = $env:username, 'Read,Write,Modify', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permission
$acl.SetAccessRule($rule)
# set new permissions
$acl | Set-Acl -Path $path