• PowerShell 2.0在远程主机上运行命令和脚本


    在前面的文章里关于持久远程线程的讨论中,曾经介绍了如何在本地主机上进入远程线程并执行命令。如果没有显式的终止线程的情况下,用户能在本地计算机上执行远程主机的命令,而PowerShell的提示符能够直接反映当前所使用线程的状况。在本章将会介绍PowerShell的内置特性,这些特性能够使用户在远程主机上运行命令和脚本。

    通过使用交互式远程管理可以克服使用Invoke-Command的一些缺点,然而这种方法也是有其局限性的。在交互式远程管理中,用户需要显式的进入或退出远程线程,这就意味着,同时只能连接到一个远程主机上,而且只能访问对应远程主机上的cmdlet和模块。如果需要让不同的cmdlet在不同的主机上都可以执行,这就做不到了。

    比如,有两台主机分别各自安装了Exchange 2010和SharePoint 2010,如果用户需要访问两台主机上各自可用的cmdlet,两台主机和本机之间均会建立一个本地线程。使用Invoke-Command会建立到远程主机的线程,并通过该线程发送脚本块执行。尽管通过交互式远程管理可以指定特定的远程线程,但是同一时间只能连接到Exchange 2010主机或者是SharePoint 2010主机当中的一台,无法实现各主机间cmdlet的共享,此时隐式远程管理就很重要了。

    隐式远程管理能将远程的命令带到本地线程中,一旦将远程命令带到本地就不需要考虑PS线程的细节了。用户可以同时导入很多远程线程到本地线程,这样就可以实现在同一本地线程中访问不同产品的技术,PowerShell会在后台为用户关注具体的执行细节。

    创建隐式远程管理

    首先可以使用New-PSSession创建持久PS线程,接下来将该线程的远程命令导入到本地线程中,具体代码如下所示:

    $s = New-PSSession -ComputerName WinServ-wfe

    Import-PSSession -Session $s

    默认情况下,Import-PSSession会导入除与当前线程中重名的命令外所有的命令,如果要导入所有的命令,需要使用-AllowClobber参数,在导入到过程中用户能看到控制台顶端会有进度条显示导入进度。如果用户导入的与本地线程同名的命令,导入的命令会隐藏或替换原始命令。这是因为导入的线程将会在导入之前将cmdlet转换为函数,而函数的优先级是高于cmdlet的,这样导入命令的优先级将会高于本地同名命令,在导入线程之后这些命令将会被导入。

    对于导入的远程命令优先级,别名将会是个例外,本地线程这种原始别名的优先级会高于导入的别名。

    导入远程线程时避免命名冲突

    Import-PSSession提供了-Prefix参数用于为导入命令在其名词添加指定的前缀,如下例所示:

    Import-PSSession -Session $s -Prefix RS

    当从远程主机导入cmdlet时会为每个cmdlet添加RS前缀,如果Get-Command用这样的方式导入到本地线程中时需要通过调用Get-RSCommand来调用该cmdlet,PowerShell将会在远程主机上隐式运行该命令。

    前面的章节中曾讨论过PowerShell在后台管理隐式远程管理,Invoke-Command会在每次执行远程命令前后,创建和销毁PS线程,对于隐式远程管理也是这样。以这种形式执行远程命令会比较缓慢,为了避免这种情况,Import-PSSession会在本地线程中向所有导入的命令添加-asJob参数。例如:

    $s = New-PSSession -ComputerName WinServ-wfe

    Import-PSSession -Session $s -Prefix RS

    Get-RSProcess -asJob

    这会将Get-RSProcess作为后台任务在远程主机运行,需要强调的是原始Get-Process是没有-asJob参数的,这里的-asJob只是作为本地线程传递给远程主机时使用的。

    向本地线程中导入模块和管理单元

    $s = New-PSSession -ComputerName WinServ-wfe

    Invoke-Command -Session $s -ScriptBlock {Import-Module ActiveDirectory}

    Import-PSSession -Session $s -Module ActiveDirectory

    在上面的例子中首先创建了PS线程,用Invoke-Command导入了活动目录模块,并将线程导入本地线程。这样就使活动目录cmdlet在本地线程中可用了。

    接下来连接到另外一个不同的远程线程并从该线程cmdlet:

    $s = New-PSSession -ComputerName WinServ-wfe

    Invoke-Command -Session $s -ScriptBlock {Add-PSSnapin Microsoft.SharePoint.PowerShell}

    Import-PSSession -Session $s

    此时在本地线程中,用户级可以访问一台主机上关于AD的cmdlet,也能访问另一台主机上的SharePoint 2010的cmdlet。这样就能通过本地线程同时管理两台主机了,而且不需要考虑创建和销毁线程的问题,PowerShell会替用户处理这些。

    隐式远程管理的局限性

    使用隐式远程管理时,用户不能导入变量或者PowerShell提供者,用户不能。Import-PSSession用Invoke-PSSession运行远程命令,可能会比较缓慢,因此所有导入的命令支持-asJob参数将命令作为远程主机上的后台任务执行,关于-asJob参数的用法可以参照前几篇文章中的具体介绍。

    总结

    隐式远程管理会将远程的命令带到本地,这项技术可以被用于导入在本地PowerShell环境中不存在的模块和管理单元,在本章中介绍了如何创建隐式远程线程以及用于Import-PSSession cmdlet的相关参数。隐式远程管理可以看作是将远程cmdlet缓存到本地,就可以同时将多台主机的cmdlet缓存到本地(当然是在考虑不重名的情况下),每个cmdlet在本地会有对应的隐射关系对应到特定远程主机上特定的cmdlet,在本地对cmdlet最终会通过远程管理机制传递到远程主机进行执行。如果是在重名的情况下,远程引入的cmdlet会在本地以函数的形式存在,故而通常的优先级会被本地cmdlet要高。因而在导入远程cmdlet之前需要为远程cmdlet在本地预设前缀,以方便与本地的cmdlet进行区分。

    赛迪网地址:http://tech.ccidnet.com/art/302/20100702/2104175_1.html

    作者: 付海军
    出处:http://fuhj02.cnblogs.com
    版权:本文版权归作者和博客园共有
    转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
    要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
    个人网站: http://txj.shell.tor.hu/

  • 相关阅读:
    div设置参数contenteditable=true
    Html事件总结
    PHP的isset()和empty()比较
    jQuery的ajax和遍历数组json代码
    PHP获取域名的几个函数使用
    关于网站favicon.ico
    PROCEDURE ANALYSE 通过分析select查询结果
    mysql 存在更新 不存在插入
    MySQL Migration Toolkit的使用
    高性能MySQL读书笔记:找出谁持有锁
  • 原文地址:https://www.cnblogs.com/fuhj02/p/1902776.html
Copyright © 2020-2023  润新知