$varname.split(',') を呼び出して、PowerShell で文字列を分割しようとしています。これは、PowerShell コンソールを使用している場合は正常に機能しますが、スクリプトを直接呼び出す場合は機能しません。
コマンド プロンプトから:powershell .\scriptname.ps1
Method invocation failed because [System.Object[]] doesn't contain a method named 'split'.
At C:\scriptname.ps1:92 char:30
+ reboot $varname.split <<<< (',')
+ CategoryInfo : InvalidOperation: (split:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
繰り返しますが、ISE で実行するか、PS プロンプトから直接実行すると、これは完全に正常に機能します。考え?
編集:以下のスクリプトを提供しました。私はPowerShellを初めて使用するので、コマンドラインから呼び出された場合にのみ変数が配列として動作するようになるものは何も見当たりません。
[string]$servers
[string]$filepath
[string]$account = $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
[string]$mode
[bool] $reboot = $FALSE
Write-Host "========================================"
Write-Host "| Windows Server Shutdown Utility v1.0 |"
Write-Host "========================================"
Function usage(){
Write-Host "Arguments are accepted in any order as long as the data follows the mode."
Write-Host "<required> [optional]"
Write-Host "Usage: powershell .\wss.ps1 <-l|-f> <data> [-account] [-reboot] [--help]"
Write-Host "`tModes"
Write-Host "`t`t-list: A list of servers, seperated by commas with no spaces inbetween"
Write-Host "`t`t`tAliases: -l"
Write-Host "`t`t`t[*] Example: `"ServerA.domain,ServerB.domain`""
Write-Host "`t`t-file: A path to a file that contains one server name on each line"
Write-Host "`t`t`tAliases: -f"
Write-Host "`t`t`t[*] Example: `"C:\allDomainServers.txt`""
Write-Host "`taccount: The domain and account to use. You will be prompted for a password."
Write-Host "`t`t`tAliases: -a, -ac"
Write-Host "`treboot: If specified, the servers will be shutdown instead of rebooted."
Write-Host "`t`t`tAliases: -r"
Write-Host "`thelp: Prints the help screen."
Write-Host "`t`t`tAliases: -h, -help, /help, /?"
Write-Host "`t`tNOTE: If no account is specified, the current user will be used."
}
Function shutdown($arr){
$arr | ForEach{
Write-Host "Attempting to shutdown $_"
Stop-Computer -computername ($_) -credential ($c) -force
}
Write-Host "Finished. Please be aware that some servers may still be in the process of shutting down."
}
Function reboot($arr){
$arr | ForEach{
Write-Host "Attempting to reboot $_"
Restart-Computer -computername ($_) -credential ($c) -force
}
Write-Host "Finished. Please be aware that some servers may still be in the process of rebooting."
}
#Parse Arguments
if($args.length -eq 0 -or $args[0] -eq "-help" -or $args[0] -eq "/help" -or $args[0] -eq "--help" -or $args[0] -eq "/?"){
usage
exit
}
for($i=0; $i -lt $args.length; $i++){
$k = $args[$i]
if($k -eq "-r" -or $k -eq "-reboot"){
$reboot = $TRUE
}elseif($k -eq "-a" -or $k -eq "-ac" -or $k -eq "-account"){
$account = $args[++$i]
}elseif((!$mode) -and ($k -eq "-l" -or $k -eq "-list")){
$servers = $args[++$i]
$mode = "list"
}elseif((!$mode) -and ($k -eq "-f" -or $k -eq "-file")){
$filepath = $args[++$i]
$mode = "file"
}
}
#Verify Account Credentials
$c = get-credential $account
if(!$c){
Write-Host "No credentials specified!"
exit
}
if($mode -eq "list"){
Write-Host "Using Mode: List"
if([string]::IsNullOrEmpty($servers)){
usage
exit
}
if($reboot){
reboot $servers.split(',')
}else{
shutdown $servers.split(',')
}
}elseif($mode -eq "file"){
Write-Host "Using Mode: File"
if([string]::IsNullOrEmpty($filepath)){
$filepath = Read-Host 'Enter the path to the file containing a list of hosts:'
}
if(!(Test-Path $filepath)){
Write-Host "Error! File doesn't exist!"
exit
}
if($reboot){
reboot (get-content $filepath)
}else{
shutdown (get-content $filepath)
}
}else{
Write-Host "Unknown Mode! Got: $mode"
exit
}
編集 2:このスクリプトを使用してさらにテストを参照してください。
for($i=0; $i -lt $args.length; $i++){
Write-Host $args[$i]
Write-Host $args[$i].GetType()
}
Powershell プロンプト:
PS C:\> .\test.ps1 asdf fdsa
asdf
System.String
fdsa
System.String
PS C:\> .\test.ps1 "asdf,fdas"
asdf,fdas
System.String
PS C:\> .\test.ps1 "asdf","fdas"
asdf fdas
System.Object[]
PS C:\> .\test.ps1 asdf,fdas
asdf fdas
System.Object[]
コマンド・プロンプト:
C:\>powershell .\test.ps1 asdf fdsa
asdf
System.String
fdsa
System.String
C:\>powershell .\test.ps1 "asdf,fdas"
asdf fdas
System.Object[]
C:\>powershell .\test.ps1 "asdf","asdfa"
asdf asdfa
System.Object[]
C:\>powershell .\test.ps1 asdf,fdas
asdf fdas
System.Object[]
引用符で囲まれた文字列の処理方法の違いに注意してください (テスト # 2)。なぜこうなった?そして、これを回避する方法はありますか?