前提・実現したいこと
リモート接続 で ネットワークドライブを割り当てたいです。
発生している問題・エラーメッセージ
ネットワークドライブの割当等を行う関数が
リモート環境だと失敗する
--追記-- 2018.10.11_9:55
$(net use $("Z" + ":") "\File-Server\Disk1")
実行時
エラーシステム エラー 58 が発生しました。
が発生
powershell
net : システム エラー 58 が発生しました。 + CategoryInfo : NotSpecified: (システム エラー 58 が発生しました。:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError 指定されたサーバーは、要求された操作を実行できません。
該当のソースコード
MainScript.ps1 ↓
powershell
#リモート操作# $ErrorActionPreference = "Stop" $Error.Clear() try { #初期処理# if (!($PSScriptRoot -eq "")) { #カレントディレクトリをスクリプトパスに設定 Set-Location -Path($PSScriptRoot) } #ライブラリパスの作成# $PSScriptRoot = $(Convert-Path -Path $(Get-Location)) $Library = "$PSScriptRoot\Library" if (Test-Path -Path $Library) { #登録関数の削除 Remove-Item Function::_* #ソースの取得 $SFuncs = $($(Get-ChildItem -Path $Library) | where {$_.Extension -eq ".ps1"} | foreach {$(Get-Content -Path $_.FullName) -join "`r`n"}) #ソースの読み込み $SFuncs | foreach {Invoke-Expression $_} } else { $PSScriptRoot = "" $Library = "" } if ($(Get-Item function::_*).count -eq 0) { throw "関数が定義されていません。" } $PC_List = @([ordered]@{ HostName = "PC01-PC" UserName = "PC01" PassWord = "PassWord" },@{ HostName = "PC02-PC" UserName = "PC02" PassWord = "PassWord" },@{ HostName = "PC03-PC" UserName = "PC03" PassWord = "PassWord" },@{ HostName = "PC04-PC" UserName = "PC04" PassWord = "PassWord" },@{ HostName = "PC05-PC" UserName = "PC05" PassWord = "PassWord" },@{ HostName = "PC06-PC" UserName = "PC06" PassWord = "PassWord" },@{ HostName = "PC07-PC" UserName = "PC07" PassWord = "PassWord" },@{ HostName = "PC08-PC" UserName = "PC08" PassWord = "PassWord" },@{ HostName = "PC09-PC" UserName = "PC09" PassWord = "PassWord" },@{ HostName = "PC10-PC" UserName = "PC10" PassWord = "PassWord" },@{ HostName = "PC11-PC" UserName = "PC11" PassWord = "PassWord" },@{ HostName = "PC12-PC" UserName = "PC12" PassWord = "PassWord" },@{ HostName = "PC13-PC" UserName = "PC13" PassWord = "PassWord" },@{ HostName = "PC14-PC" UserName = "PC14" PassWord = "PassWord" },@{ HostName = "PC15-PC" UserName = "PC15" PassWord = "PassWord" },@{ HostName = "PC16-PC" UserName = "PC16" PassWord = "PassWord" },@{ HostName = "PC17-PC" UserName = "PC17" PassWord = "PassWord" },@{ HostName = "PC18-PC" UserName = "PC18" PassWord = "PassWord" },@{ HostName = "PC19-PC" UserName = "PC19" PassWord = "PassWord" },@{ HostName = "PC20-PC" UserName = "PC20" PassWord = "PassWord" } ) $PS_List = $PC_List | foreach{New-Object psobject -Property $_} $Info = $PS_List | where {$_.UserName -like "PC01"} if ($Info -eq $null) { return $false } # セキュアストリングの作成(パスワードの暗号化) $sec_str = ConvertTo-SecureString $Info.PassWord -AsPlainText -Force # Credential オプションに指定するオブジェクトのインスタンス生成 $psc = New-Object System.Management.Automation.PsCredential($Info.UserName, $sec_str) # New-PSSession コマンドによるセッションの生成 $sess = New-PSSession -ComputerName $Info.HostName -Credential $psc if ($sess -ne $null) { #Get-PSSession # セッションの確認 Invoke-Command -Session $sess -ScriptBlock {$args[0] | foreach {Invoke-Expression $_}} -ArgumentList @($SFuncs,"") $Block08 = { "管理者権限 : $(_AuthorityValidation)" _Set_Drive -Name "Z" -Root "\File-Server\Disk1" _Get_DriveInfo -Name "Z" } # コマンドをリモートホスト上で実行する Invoke-Command -Session $sess -ScriptBlock $Block08 $null = Remove-PSSession -Session $sess # セッションを削除 } if ($Error.Count -ne 0) { $Info } } catch { Write-Host $Error }
「MainScript.ps1」と同じ階層の「Library」フォルダ内のスクリプト
System.ps1 ↓
powershell
<# システム関連 #> function _Set_Drive ([string]$Name, [string]$Root) { [OutputType([bool])] <# New-PSDrive -Name HKCC -PSProvider Registry -Root HKEY_CURRENT_CONFIG ネットワークドライブ、又は仮想ドライブを設定する [String]$Name : 設定するドライブレターを指定します。 [String]$Root : 設定するRootPathを指定します。 [Bool]返値 : 正常に完了したか #> #ドライブの解除 $null = if(!(_Remove_Drive -Name $Name)) { Write-Host "ドライブの解除に失敗しました" return $false } #ドライブの設定 $ErrorActionPreference = "silentlycontinue" switch ($Root) { {$_.Substring(0,2) -eq "\"} { #ネットワークドライブの設定 [Bool]$Return = $(net use $($Name + ":") $Root)-as 'bool' break } Default { #仮想ドライブの設定 [Bool]$Return = !(subst $($Name + ":") $Root) break } } $ErrorActionPreference = "continue" #再接続設定 $null = net use /persistent:yes return $Return } function _Remove_Drive ([string]$Name) { [OutputType([bool])] <# ネットワークドライブ、又は仮想ドライブを解除する [String]$Name : 設定するドライブレターを指定します。 [String]$Root : 設定するRootPathを指定します。 [Bool]返値 : 正常に完了したか #> #ドライブの解除 $ErrorActionPreference = "silentlycontinue" $null = switch ($(_Get_DriveInfo -Name $Name)) { {$_ -eq $null} { return $true break } {$_.Type -eq 'Hardware'} { return $false break } {$_.Type -eq 'NetWork'} { #ネットワークドライブの割当解除 [bool]$Return = $(net use $($Name + ":") /delete /y) -as 'bool' return $Return break } {$_.Type -eq 'Phantom'} { #仮想ドライブの解除 [bool]$Return = !(Subst $($Name + ":") /d) break } } $ErrorActionPreference = "continue" return $Return } function _Get_DriveInfo ([string]$Name) { [OutputType([psobject])] #引数で指定されたドライブの情報を返す# [System.Management.Automation.PSDriveInfo]$Info = Get-PSDrive | Where-Object{$_.Name -eq $Name} if($Info -eq $null) { return $null } $NetDriveRoot = $($(Get-WMIObject -query $("Select * From Win32_LogicalDisk Where DeviceID='" + $Name + ":' and DriveType = 4")).ProviderName) if($NetDriveRoot -eq $null) { $SubstDrive = $(subst) | Where-Object{$_.substring(0,$_.indexof(':')) -eq $Name} if ($SubstDrive -eq $null) { $DriveInfo = [ordered]@{Name = $Name ; Root = $Info.Root ; Type = "Hardware"} } else { $DriveInfo = [ordered]@{Name = $Name ; Root = $($SubstDrive -split '\:\\: => ')[1] ; Type = "Phantom"} } } else { $DriveInfo = [ordered]@{Name = $Name ; Root = $NetDriveRoot ; Type = "NetWork"} } $Return = $DriveInfo | foreach{New-Object psobject -Property $_} return $Return } function _AuthorityValidation () { [OutputType([bool])] <# 管理者権限で実行されているか返す [Bool]返値 : 管理者権限か #> $Admin = $(([Security.Principal.WindowsPrincipal] ` [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` [Security.Principal.WindowsBuiltInRole] "Administrator")) return $Admin } Function _ZoneDel($FineFullName){ <# ファイルのZone情報を削除する (インターネットから入手したフラグの削除) #> Remove-Item -Path $FineFullName -Stream *Zone* } function _Get_SPFoderPath([string]$Str_Folder) { <# 特殊フォルダのパス取得 'MyDocuments' 'MyMusic' 'MyPictures' 'MyVideos' 'Desktop' 'Fonts' 'SendTo' 'Startup' 'ApplicationData' #> return [Environment]::GetFolderPath($Str_Folder) }
試したこと
全て 管理者権限 なのが悪いのかと思い
試しに管理者権限でISEを開き「System.ps1」を単体で開いて「F5」キーで実行した後
ISEのコンソールで直接_Set_Drive -Name "Z" -Root "\File-Server\Disk1"
を
実行してみたらZドライブのショートカットを叩かないとつながりませんでしたが
コマンドの実行自体は成功しました。
失敗したときの $(net use $($Name + ":") $Root)
の返り値を見てみたのですが
何も帰ってきてないようでした。
--追記-- 2018.10.11_9:55
関数側を変更して$(net use $($Name + ":") $Root)
の返り値等を受け取ろうとしていたのが悪かったようで$Block08 =
の箇所に直接$(net use $("Z" + ":") "\File-Server\Disk1")
を追加してみたところシステム エラー 58 が発生しました。
とエラーが帰ってきていることがわかりました。
調べたところWindows のサポートにてエラー 58がでる原因の一つとしてSMBv1 が無効になっていることが分かったので試にEnable-WindowsOptionalFeature -Online -FeatureName smb1protocolでSMBv1を有効にしてから試してみたのですがだめでした。
--追記--
ルータのファイアウォール設定で「NBTとMicrosoft-DSのルーティングを禁止する」
なんて項目があったので切ってみたのですがだめでした。
補足情報(FW/ツールのバージョンなど)
Win10 Home & Pro
Powershell Version = Default
まだ回答がついていません
会員登録して回答してみよう