#powershell
#powershell
Вопрос:
Я борюсь со своим скриптом — по какой-то причине PSDrive, который создает мой скрипт, недоступен для разрешения пути. В общем, в скрипте есть функция «Start-RDP», которая запускает RDP с предварительно загруженными учетными данными (автологон), а затем проверяет, обновлен ли профиль Powershell на целевом хосте (путем сравнения хэшей файлов). Однако для того, чтобы скрипт мог получить доступ к удаленной файловой системе, мне нужно смонтировать его как PSDrive. Вот сценарий, который является оскорбительным. Все переменные задаются правильно в течение этого времени, указанного выше в сценарии.
New-PSDrive -name "$computername" -Root "\$computernamec$" -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$DocumentsWindowsPowerShell) {
$ProfileHash = Get-FileHash $Profile.CurrentUserAllHosts
if (!(Test-Path "${computername}:$Userpath$DocumentsWindowsPowerShellprofile.ps1")) { Copy-Item -Force -Path "$env:userprofileWindowsPowershellprofile.ps1" -Destination "${computername}:$Userpath$DocumentsWindowsPowerShell" }
$RemoteProfileHash = Get-FileHash "${computername}:$Userpath$DocumentsWindowsPowerShellprofile.ps1"
if ($ProfileHash -ne $RemoteProfileHash) { Copy-Item -Force -Path "$env:userprofile$DocumentsWindowsPowershellprofile.ps1" -Destination "${computername}:$userpath$DocumentsWindowsPowerShell" }
}
Ошибка, которую я получаю, находится на втором тестовом пути (где я проверяю, существует ли каталог WindowsPowerShell).
Resolve-Path : Cannot find drive. A drive with the name 'server01' does not exist.
At C:windowssystem32windowspowershellv1.0ModulesMicrosoft.PowerShell.UtilityMicrosoft.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. Разрешить-Путь нигде не указан в блоке кода, который у вас есть в вопросе.
2. Путь разрешения вообще нигде не указан. Я предположил, что тестовый путь использует командлет resolve-path для правильной работы?
Ответ №1:
Я вижу, что вы там сделали.
Проблема в том, что вы используете переменную $Profile.CurrentUserAllHosts
, которую powershell пытается разрешить, как полное имя переменной. $Profile
это строка, у которой нет вызываемого свойства CurrentUserAllHosts
. Для исправления используйте следующее:
$ProfileHash = Get-FileHash "${Profile}.CurrentUserAllHosts"
После еще нескольких исследований я нашел этот фрагмент в блоге
такие команды, как Resolve-Path и $PSCmdlet.GetUnresolvedProviderPathFromPSPath() не нормализует пути UNC должным образом, даже если их обрабатывает поставщик файловой системы.
Который затем ссылается на Get-NormalizedFileSystemPath
скрипт в technet.
Поскольку 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 '\servershare.SomeFolder..SomeOtherFolderFile.txt'
Returns '\servershareSomeOtherFolderFile.txt'
.EXAMPLE
'\serverc$.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::\serverc$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
Комментарии:
1. Запуск
$profile | select *
показывает, что$profile
автоматическая переменная имеет несколько свойств PowerShell note, привязанных к ней для разных комбинаций пользователь / хост, в дополнение к строковому значению «текущий пользователь / текущий хост».