Powershell Invoke-Command Problem
Hallo liebe Gemeinde,
ich bin gerade dabei mir über Powershell ISE meine Scriptsammlung zusammen zu führen. Im ersten Schritt hatte ich mir eine "kleine" scriptdatei geschrieben in der alle Befehle per Auswahl ausgeführt werden:
Im 2. Schritt bin ich gerade dabei mir eine GUI drüber zu basteln damit ich (wenn fertig) mit wenigen Klicks meine Aufgaben erledigen kann.
Hier hänge ich gerade bei einem eigentlich kleinen Problem welches ich aber nun endlich mal gelöst haben will und einfach keine Ideen mehr habe.
Folgendes:
per
versuche ich das Passwort eines Users zurückzusetzen und bekomme aber den Fehler:
Das Argument für den Parameter "Identity" kann nicht überprüft werden. Das Argument ist NULL. Geben Sie ein Argument an, das nicht NULL ist, und führen Sie dann
den Befehl erneut aus.
+ CategoryInfo : InvalidData: ( [Set-ADAccountPassword], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADAccountPassword
+ PSComputerName : DC
Wenn ich aber den Befehl per Powershell direkt ausführe mit ausgefüllten Credentials funktioniert es.
Es scheint, das die Text Box die ich zur user eingabe nutzen möchte NICHT abgefragt wird.
Hier mal das komplette Script in der Hoffnung das mir jemand helfen kann.
Vielen Dank schon mal
Grüße
Merlin
ich bin gerade dabei mir über Powershell ISE meine Scriptsammlung zusammen zu führen. Im ersten Schritt hatte ich mir eine "kleine" scriptdatei geschrieben in der alle Befehle per Auswahl ausgeführt werden:
Import-Module ActiveDirectory
Add-PSSnapin quest.activeroles.admanagement
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
do {
do {
write-host ""
write-host "X - Exit"
write-host "A - Ausgabe der GPO´s"
write-host "B - Export GPO"
write-host "C - Import GPO"
write-host "D - Server Edition Upgrade"
write-host "E - Change Product Key"
write-host "F - Set Global User Identity"
write-host "G - Change User Password"
write-host "H - Redirect an OU"
write-host "I - Enable Mailbox for Users in OU"
write-host "J - Add Mailbox for User in specified OU"
write-host "K - ADD OU"
write-host "L - ADD Group"
write-host "M - New Email Address Policy"
write-host "N - Forward Mails to SMTP Address"
write-host "O - Disable Forwarding to SMTP Address"
write-host "P - View Forwarding Status for User"
write-host "Q - New Distribution list"
write-host "R - Add Users to Distribution list from a csv file"
write-host "S - Command 4"
write-host "T - Command 4"
write-host "U - Command 4"
write-host "V - Command 4"
write-host "W - Command 4"
write-host "Y - Command 4"
write-host "Z - Command 4"
write-host ""
write-host -nonewline "Select command and press Enter: "
$choice = read-host
write-host ""
$ok = @("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","Y","Z","X") -contains $choice
if ( -not $ok) { write-host "Invalid selection" }
}
until ( $ok )
switch ( $choice ) {
"A" {
Get-GPO -all
break
}
"B" {
write-host -nonewline "GPO NAME and press Enter: "
$Name = read-host
write-host -nonewline "Export Path and press Enter: "
$PATH = read-host
Backup-GPO -Name $NAME -Path $PATH
break
}
"C" {
write-host -nonewline "GPO NAME and press Enter: "
$Name = read-host
write-host -nonewline "NEW GPO NAME and press Enter: "
$NAME1 = read-host
write-host -nonewline "Import Path and press Enter: "
$PATH = read-host
Import-GPO -BackupGPOName $NAME -TargetName $NAME1 -CreateIfNeeded -Path $PATH
break
}
"D" {
write-host -nonewline "Doesnt work with Domain Controllern"
write-host -nonewline "Edition Name: "
$Product = read-host
write-host -nonewline "Product Key: "
$ProductKey = read-host
DISM /online /Set-Edition: $Product /ProductKey: $ProductKey /AcceptEula
break
}
"E" {
write-host -nonewline "Product Key: "
$ProductKey = read-host
slmgr -ipk $ProductKey
break
}
"F" {
write-host -nonewline "OU with Employees: "
$OU = read-host
write-host -nonewline "Hosted OU of OU Employees: "
$OU1 = read-host
write-host -nonewline "Next Hosted OU (leave blank if no more OU is present: "
$OU2 = read-host
write-host -nonewline "Next Hosted OU (leave blank if no more OU is present: "
$OU3 = read-host
write-host -nonewline "Domain Name without .local: "
$DOMAIN = read-host
write-host -nonewline "Enter City: "
$city = read-host
write-host -nonewline "Enter Street: "
$street = read-host
write-host -nonewline "Enter Postal Code: "
$PostalCode = read-host
write-host -nonewline "Enter State: "
$State = read-host
write-host -nonewline "Enter Organization: "
$Organization = read-host
Get-ADUser -SearchBase ou= $OU,ou= $OU1,ou= $OU2,ou= $OU3,dc= $DOMAIN,dc=local -Filter * | Set-ADUser -Identity $_ -City $city -StreetAddress $street -PostalCode $PostalCode -State $State -Company $Organization
break
}
"G" {
write-host -nonewline "Username: "
$USER = read-host
write-host -nonewline "New Password: "
Set-ADAccountPassword $USER -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True
break
}
"H" {
write-host -nonewline "OU Destination: "
$OU = read-host
write-host -nonewline "overall OU: "
$OU1 = read-host
write-host -nonewline "Domain without .local: "
$DOMAIN = read-host
redircmp OU= $OU,OU= $OU1,DC= $DOMAIN,DC=local
break
}
"I" {
write-host -nonewline "Enter OU like domain.local/OU/OU1/OU with Employees: "
$OU = read-host
write-host -nonewline "which Database: "
$DATABASE = read-host
Get-User –OrganizationalUnit $OU | Enable-Mailbox -Database $DATABASE
break
}
"J" {
write-host -nonewline "Enter OU like domain.local/OU/OU1/OU with Employees: "
$OU = read-host
write-host -nonewline "which Database: "
$DATABASE = read-host
Get-User –OrganizationalUnit $OU | Enable-Mailbox -Database $DATABASE
break
}
"K" {
write-host -nonewline "Enter OU like OU=NAME,OU=NAME,DC=DOMAIN,DC=local: "
$OU = read-host
dsadd ou $OU
break
}
"L" {
write-host -nonewline "Enter Group like CN=NAME,OU=NAME,DC=DOMAIN,DC=local: "
$OU = read-host
dsadd group $OU
break
}
"M" {
write-host -nonewline "New Name for Address Policy: "
$NAME = read-host
write-host -nonewline "Conditional State or Province: "
$STATE = read-host
write-host -nonewline "Address Policy @Domainname: "
$SMTP = read-host
New-EmailAddressPolicy -Name $NAME -IncludedRecipients MailboxUsers -ConditionalStateorProvince $STATE -EnabledEmailAddressTemplates $SMTP
break
}
"N" {
write-host -nonewline "Username: "
$NAME = read-host
write-host -nonewline "Forwarding SMTP Address: "
$SMTP = read-host
set-mailbox -Identity $NAME -DeliverToMailboxAndForward $true -ForwardingSmtpAddress $SMTP
break
}
"O" {
write-host -nonewline "Username: "
$NAME = read-host
set-mailbox -Identity $NAME -DeliverToMailboxAndForward $false -ForwardingSmtpAddress $null
break
}
"P" {
write-host -nonewline "Username: "
$NAME = read-host
Get-Mailbox -Identity $NAME | fl *Forwarding*
break
}
"Q" {
write-host -nonewline "Distribution Name: "
$NAME = read-host
write-host -nonewline "Sam Account Name: "
$SAM = read-host
write-host -nonewline "Alias Name: "
$ALIAS = read-host
new-DistributionGroup -Name $NAME -SamAccountName $SAM -Alias $ALIAS
break
}
"R" {
write-host -nonewline "CSV file location: "
$CSV = read-host
write-host -nonewline "Distribution list: "
$DISTR = read-host
import-csv $CSV | foreach {add-distributiongroupmember -id $DISTR $_.PrimarySmtpAddress }
break
}
}
}
until ( $choice -eq "X" )
Im 2. Schritt bin ich gerade dabei mir eine GUI drüber zu basteln damit ich (wenn fertig) mit wenigen Klicks meine Aufgaben erledigen kann.
Hier hänge ich gerade bei einem eigentlich kleinen Problem welches ich aber nun endlich mal gelöst haben will und einfach keine Ideen mehr habe.
Folgendes:
per
function resetPW {
$wks=$InputBox.text;
$User=$InputBoxUser.text;
#$pwd=$InputBoxPW.text;
$UserResult=Invoke-Command -ComputerName $wks -ScriptBlock{Set-ADAccountPassword $User -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True}
} #end
Das Argument für den Parameter "Identity" kann nicht überprüft werden. Das Argument ist NULL. Geben Sie ein Argument an, das nicht NULL ist, und führen Sie dann
den Befehl erneut aus.
+ CategoryInfo : InvalidData: ( [Set-ADAccountPassword], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.SetADAccountPassword
+ PSComputerName : DC
Wenn ich aber den Befehl per Powershell direkt ausführe mit ausgefüllten Credentials funktioniert es.
Set-ADAccountPassword user1 -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True
Hier mal das komplette Script in der Hoffnung das mir jemand helfen kann.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") #loading the necessary .net libraries (using void to suppress output)
#Window Options
$Form = New-Object System.Windows.Forms.Form #creating the form (this will be the "primary" window)
$Form.Size = New-Object System.Drawing.Size(1024,768) #the size in px of the window length, height
Add-Type -AssemblyName System.Windows.Forms
$Image = [system.drawing.image]::FromFile("$($Env:Public)\water.jpg")
$Form.BackgroundImage = $Image
$Form.BackgroundImageLayout = "Stretch" # None, Tile, Center, Stretch, Zoom
$Form.StartPosition = "CenterScreen" #loads the window in the center of the screen
$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedToolWindow #modifies the window border
$Form.Text = "Powershell GUI Utility" #window description
#Funktion PING
function pingInfo {
$wks=$InputBox.text; #takes the text from the input box into the variable $wks
$pingResult=ping $wks | fl | out-string;
$outputBox.text=$pingResult #send the ping results to the output box
} #end
#Funktion NSlookup
function nsLookup {
$wks=$InputBox.text; #takes the text from the input box into the variable $wks
$lookupResult=[System.Net.Dns]::GetHostAddresses($wks) | fl | out-string;
$outputBox.text=$lookupResult #send the nslookup results to the output box
} #end
#Funktion GPO
function GPO {
$wks=$InputBox.text; #takes the text from the input box into the variable $wks
$GPOResult=Invoke-Command -ComputerName $wks -ScriptBlock { Get-GPO -all } | fl | out-string;
$outputBox.text=$GPOResult #send the results to the output box
} #end
#Funktion Reset Password
function resetPW {
$wks=$InputBox.text;
$User=$InputBoxUser.text;
#$pwd=$InputBoxPW.text;
$UserResult=Invoke-Command -ComputerName $wks -ScriptBlock{Set-ADAccountPassword $User -NewPassword $newpwd -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True}
} #end
#Funktion Ad User
function adUser {
$wks=$InputBox.text; #takes the text from the input box into the variable $wks
$UserResult=Invoke-Command -ComputerName $wks -ScriptBlock { Get-ADUser -Filter *} | fl | out-string; #populate the var with the value you selected
$outputBox.text=$UserResult #send the results to the output box
} #end procInfo
#Funktion SMTP Forwarding Status
function smtpFWstats {
$Name=$InputboxUser.text;
$wks=$InputBox.text; #takes the text from the input box into the variable $wks
$smtpFWstatus=Get-Mailbox -Resultsize Unlimited | Where {$_.ForwardingAddress -ne $null} | Select Name, @{Expression={$_.ForwardingAddress};Label="Forwarded to"}, @{Expression={$_.DeliverToMailboxAndForward};Label="Mailbox & Forward"} | fl | out-string; #populate the var with the value you selected
$outputBox.text=$smtpFWstatus #send the results to the output box
} #end procInfo
#Start Textfields
#Input
$InputBox = New-Object System.Windows.Forms.TextBox #creating the text box
$InputBox.Location = New-Object System.Drawing.Size(10,120) #location of the text box (px) in relation to the primary window's edges (length, height)
$InputBox.Size = New-Object System.Drawing.Size(150,20) #the size in px of the text box (length, height)
$InputBox.Text = "Computername"
$Form.Controls.Add($InputBox) #activating the text box inside the primary window
#Input Username
$InputBoxUser = New-Object System.Windows.Forms.TextBox #creating the text box
$InputBoxUser.Location = New-Object System.Drawing.Size(165,120) #location of the text box (px) in relation to the primary window's edges (length, height)
$InputBoxUser.Size = New-Object System.Drawing.Size(150,20) #the size in px of the text box (length, height)
$InputBoxUser.Text = "User Logon Name"
$Form.Controls.Add($InputBoxUser) #activating the text box inside the primary window
#Input Password
#$InputBoxPW = New-Object System.Windows.Forms.TextBox #creating the text box
#$InputBoxPW.Location = New-Object System.Drawing.Size(320,120) #location of the text box (px) in relation to the primary window's edges (length, height)
#$InputBoxPW.Size = New-Object System.Drawing.Size(150,20) #the size in px of the text box (length, height)
#$InputBoxPW.UseSystemPasswordChar = $True
#$InputBoxPW.Text = "Password"
#$Form.Controls.Add($InputBoxPW) #activating the text box inside the primary window
#Output
$outputBox = New-Object System.Windows.Forms.TextBox #creating the text box
$outputBox.Location = New-Object System.Drawing.Size(10,150) #location of the text box (px) in relation to the primary window's edges (length, height)
$outputBox.Size = New-Object System.Drawing.Size(1000,500) #the size in px of the text box (length, height)
$outputBox.MultiLine = $True #declaring the text box as multi-line
$outputBox.ScrollBars = "Vertical" #adding scroll bars if required
$outputBox.Font = New-Object System.Drawing.Font("Verdana",8,[System.Drawing.FontStyle]::Italic) #Textbox Font
$Form.Controls.Add($outputBox) #activating the text box inside the primary window
#End Textfields
#Ping Buttons
$Button = New-Object System.Windows.Forms.Button #create the button
$Button.Location = New-Object System.Drawing.Size(20,35) #location of the button (px) in relation to the primary window's edges (length, height)
$Button.Size = New-Object System.Drawing.Size(100,23) #the size in px of the button (length, height)
$Button.Text = "Ping" #labeling the button
$Button.Cursor = [System.Windows.Forms.Cursors]::Hand
$Button.BackColor = [System.Drawing.Color]::LightGreen
$Button.Font = New-Object System.Drawing.Font ("Verdana",10, [System.Drawing.FontStyle]::Regular)
$Button.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($Button) #activating the button inside the primary window
$Button.Add_Click({pingInfo})
#NSlookup Buttons
$Button = New-Object System.Windows.Forms.Button #create the button
$Button.Location = New-Object System.Drawing.Size(20,60) #location of the button (px) in relation to the primary window's edges (length, height)
$Button.Size = New-Object System.Drawing.Size(100,23) #the size in px of the button (length, height)
$Button.Text = "NS Lookup" #labeling the button
$Button.Cursor = [System.Windows.Forms.Cursors]::Hand
$Button.BackColor = [System.Drawing.Color]::LightGreen
$Button.Font = New-Object System.Drawing.Font ("Verdana",10, [System.Drawing.FontStyle]::Regular)
$Button.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($Button) #activating the button inside the primary window
$Button.Add_Click({nsLookup})
#Get GPO Button
$Button = New-Object System.Windows.Forms.Button #create the button
$Button.Location = New-Object System.Drawing.Size(20,10) #location of the button (px) in relation to the primary window's edges (length, height)
$Button.Size = New-Object System.Drawing.Size(100,23) #the size in px of the button (length, height)
$Button.Text = "Get GPO´s" #labeling the button
$Button.Cursor = [System.Windows.Forms.Cursors]::Hand
$Button.BackColor = [System.Drawing.Color]::LightGreen
$Button.Font = New-Object System.Drawing.Font("Verdana",10,[System.Drawing.FontStyle]::Regular)
$Button.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($Button) #activating the button inside the primary window
$Button.Add_Click({GPO})
#Set New User Password
$Button = New-Object System.Windows.Forms.Button #create the button
$Button.Location = New-Object System.Drawing.Size(120,10) #location of the button (px) in relation to the primary window's edges (length, height)
$Button.Size = New-Object System.Drawing.Size(130,23) #the size in px of the button (length, height)
$Button.Text = "Reset Password" #labeling the button
$Button.Cursor = [System.Windows.Forms.Cursors]::Hand
$Button.BackColor = [System.Drawing.Color]::LightGreen
$Button.Font = New-Object System.Drawing.Font("Verdana",10,[System.Drawing.FontStyle]::Regular)
$Button.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($Button) #activating the button inside the primary window
$Button.Add_Click({resetPW})
#Get AD User Button
$Button = New-Object System.Windows.Forms.Button #create the button
$Button.Location = New-Object System.Drawing.Size(120,35) #location of the button (px) in relation to the primary window's edges (length, height)
$Button.Size = New-Object System.Drawing.Size(130,23) #the size in px of the button (length, height)
$Button.Text = "Get All AD User" #labeling the button
$Button.Cursor = [System.Windows.Forms.Cursors]::Hand
$Button.BackColor = [System.Drawing.Color]::LightGreen
$Button.Font = New-Object System.Drawing.Font("Verdana",10,[System.Drawing.FontStyle]::Regular)
$Button.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($Button) #activating the button inside the primary window
$Button.Add_Click({adUser})
#SMTP Forward Status
$Button = New-Object System.Windows.Forms.Button #create the button
$Button.Location = New-Object System.Drawing.Size(400,10) #location of the button (px) in relation to the primary window's edges (length, height)
$Button.Size = New-Object System.Drawing.Size(130,23) #the size in px of the button (length, height)
$Button.Text = "SMTP FW Status" #labeling the button
$Button.Cursor = [System.Windows.Forms.Cursors]::Hand
$Button.BackColor = [System.Drawing.Color]::LightBlue
$Button.Font = New-Object System.Drawing.Font("Verdana",10,[System.Drawing.FontStyle]::Regular)
$Button.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($Button) #activating the button inside the primary window
$Button.Add_Click({smtpFWstats})
#Cancel Buttons
$ExitButton = New-Object System.Windows.Forms.Button #create the button
$ExitButton.Location = New-Object System.Drawing.Size(900,710) #location of the button (px) in relation to the primary window's edges (length, height)
$ExitButton.Size = New-Object System.Drawing.Size(100,23) #the size in px of the button (length, height)
$ExitButton.Text = "Exit" #labeling the button
$ExitButton.Add_Click({}) #the action triggered by the button
$Form.Controls.Add($ExitButton) #activating the button inside the primary window
$ExitButton.Add_Click({$Form.Close()})
#activate
[void] $Form.ShowDialog()
[void] $Form.Add_Shown({$Form.Activate()})
Vielen Dank schon mal
Grüße
Merlin
Please also mark the comments that contributed to the solution of the article
Content-ID: 248690
Url: https://administrator.de/contentid/248690
Printed on: December 5, 2024 at 22:12 o'clock
2 Comments
Latest comment
Hallo Merlin,
dein Problem ist, dass dein Befehl bzw. der Scriptblock auf dem Remotecomputer ausgeführt wird und somit dort deine Variablen nicht vorhanden sind ! Um das zu umgehen kannst du im Befehl invoke-command mit dem Parameter -argumentlist ein Array an Variablen als Argumente an den Scriptblock übergeben die dann im Scriptblock mit $args , $args[1], usw abgerufen werden können:
Grüße Uwe
dein Problem ist, dass dein Befehl bzw. der Scriptblock auf dem Remotecomputer ausgeführt wird und somit dort deine Variablen nicht vorhanden sind ! Um das zu umgehen kannst du im Befehl invoke-command mit dem Parameter -argumentlist ein Array an Variablen als Argumente an den Scriptblock übergeben die dann im Scriptblock mit $args , $args[1], usw abgerufen werden können:
$UserResult=Invoke-Command -ComputerName $wks -argumentlist $User,$newpwd -ScriptBlock{Set-ADAccountPassword $args -NewPassword $args[1] -Reset -PassThru | Set-ADuser -ChangePasswordAtLogon $True} }