自动配置文件更新Powershell - 找不到驱动器

时间:2014-06-16 11:07:44

标签: powershell

我正在努力使用我的脚本 - 出于某种原因,我的脚本创建的PSDrive无法访问Resolve-Path。 通常,在脚本中有“Start-RDP”功能,它使用预加载的凭据(自动登录)启动RDP,然后检查目标主机上的Powershell配置文件是否是最新的(通过比较文件数据)。但是,为了让脚本访问远程文件系统,我需要将其安装为PSDrive。 这是冒犯的脚本。在此期间,所有变量都在脚本中正确设置。

New-PSDrive -name "$computername" -Root "\\$computername\c$" -Credential $CurrentCred -PSProvider FileSystem | out-null
Start-Sleep -Seconds 10
while (!(Test-Path -Path ${Computername}:\$Userpath\$Documents\)) { Write-host "UserDir not created yet!" ; start-sleep -Seconds 5 }

if (Test-Path -Path ${Computername}:\$Userpath\$Documents\WindowsPowerShell) { 
$ProfileHash = Get-FileHash $Profile.CurrentUserAllHosts
if (!(Test-Path "${computername}:\$Userpath\$Documents\WindowsPowerShell\profile.ps1")) { Copy-Item -Force -Path "$env:userprofile\WindowsPowershell\profile.ps1" -Destination "${computername}:\$Userpath\$Documents\WindowsPowerShell\" }
$RemoteProfileHash = Get-FileHash "${computername}:\$Userpath\$Documents\WindowsPowerShell\profile.ps1"
if ($ProfileHash -ne $RemoteProfileHash) { Copy-Item -Force -Path "$env:userprofile\$Documents\WindowsPowershell\profile.ps1" -Destination "${computername}:\$userpath\$Documents\WindowsPowerShell\" }
 } 

我得到的错误是在第二个Test-Path(我检查WindowsPowerShell目录是否存在)。

Resolve-Path : Cannot find drive. A drive with the name 'server01' does not exist.
At C:\windows\system32\windowspowershell\v1.0\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psm1:35 char:32
+             $pathsToProcess += Resolve-Path $Path | Foreach-Object ProviderPath
+                                ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (server01:String) [Resolve-Path], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand

我无法追查此错误发生的具体原因。驱动器在那里(我使用PSBreakpoint检查)

我现在有点困惑,你有什么想法吗?

1 个答案:

答案 0 :(得分:-1)

我看到你在那里做了什么。

问题是你正在使用powershell试图解析的变量$Profile.CurrentUserAllHosts作为一个完整的变量名。 $Profile是一个字符串,没有名为CurrentUserAllHosts的属性。要解决此问题,请使用以下命令:

$ProfileHash = Get-FileHash "${Profile}.CurrentUserAllHosts"

经过一番调查后,我在blog

上找到了这个代码段
  

像Resolve-Path和$ PSCmdlet.GetUnresolvedProviderPathFromPSPath()这样的命令不会正确地规范化UNC路径,即使文件系统提供程序处理它们也是如此。

然后链接到technet上的Get-NormalizedFileSystemPath脚本。

由于Get-FileHash是系统提供的方法,因此您需要Get-NormalizedFileSystemPath才能将其传递给Get-FileHash

为了后人,这是脚本:

function Get-NormalizedFileSystemPath
{
    <#
    .Synopsis
       Normalizes file system paths.
    .DESCRIPTION
       Normalizes file system paths.  This is similar to what the Resolve-Path cmdlet does, except Get-NormalizedFileSystemPath also properly handles UNC paths and converts 8.3 short names to long paths.
    .PARAMETER Path
       The path or paths to be normalized.
    .PARAMETER IncludeProviderPrefix
       If this switch is passed, normalized paths will be prefixed with 'FileSystem::'.  This allows them to be reliably passed to cmdlets such as Get-Content, Get-Item, etc, regardless of Powershell's current location.
    .EXAMPLE
       Get-NormalizedFileSystemPath -Path '\\server\share\.\SomeFolder\..\SomeOtherFolder\File.txt'

       Returns '\\server\share\SomeOtherFolder\File.txt'
    .EXAMPLE
       '\\server\c$\.\SomeFolder\..\PROGRA~1' | Get-NormalizedFileSystemPath -IncludeProviderPrefix

       Assuming you can access the c$ share on \\server, and PROGRA~1 is the short name for "Program Files" (which is common), returns:

       'FileSystem::\\server\c$\Program Files'
    .INPUTS
       String
    .OUTPUTS
       String
    .NOTES
       Paths passed to this command cannot contain wildcards; these will be treated as invalid characters by the .NET Framework classes which do the work of validating and normalizing the path.
    .LINK
       Resolve-Path
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('PSPath', 'FullName')]
        [string[]]
        $Path,

        [switch]
        $IncludeProviderPrefix
    )

    process
    {
        foreach ($_path in $Path)
        {
            $_resolved = $_path

            if ($_resolved -match '^([^:]+)::')
            {
                $providerName = $matches[1]

                if ($providerName -ne 'FileSystem')
                {
                    Write-Error "Only FileSystem paths may be passed to Get-NormalizedFileSystemPath.  Value '$_path' is for provider '$providerName'."
                    continue
                }

                $_resolved = $_resolved.Substring($matches[0].Length)
            }

            if (-not [System.IO.Path]::IsPathRooted($_resolved))
            {
                $_resolved = Join-Path -Path $PSCmdlet.SessionState.Path.CurrentFileSystemLocation -ChildPath $_resolved
            }

            try
            {
                $dirInfo = New-Object System.IO.DirectoryInfo($_resolved)
            }
            catch
            {
                $exception = $_.Exception
                while ($null -ne $exception.InnerException)
                {
                    $exception = $exception.InnerException
                }

                Write-Error "Value '$_path' could not be parsed as a FileSystem path: $($exception.Message)"

                continue
            }

            $_resolved = $dirInfo.FullName

            if ($IncludeProviderPrefix)
            {
                $_resolved = "FileSystem::$_resolved"
            }

            Write-Output $_resolved
        }
    } # process

} # function Get-NormalizedFileSystemPath