Powershell not recognizing boolean argument - powershell

I have the following PS script
param (
# FQDN or IP address of the Domain Controller
[Parameter(Mandatory=$True)]
[string]$ADaddress,
# Active directory domain name
# example: directory.local
[Parameter(Mandatory=$True)]
[string]$ADDomainName,
# Domain admin
# example: administrator#directory.local
[Parameter(Mandatory=$True)]
[string]$domainAdmin,
# Domain admin password
[Parameter(Mandatory=$True)]
[string]$domainAdminPassword,
# User to be added
# example: testUser
[Parameter (Mandatory=$True)]
[string]$newUsername,
# Password of th user to be added
# example: 1!2#4%6
[Parameter (Mandatory=$True)]
[string]$newPassword,
# SAM account name of the user to added
# example: testuser
[Parameter (Mandatory=$True)]
[string]$newSamAccountName,
# Display name of the user to added
# example: "Test user for test purposes"
[Parameter (Mandatory=$True)]
[string]$newUserDisplayName
)
$domainAdminSecurePassword = $domainAdminPassword | ConvertTo-SecureString -asPlainText -Force
$domainAdminCredential = New-Object System.Management.Automation.PSCredential($domainAdmin, $domainAdminSecurePassword)
$newUserSecurePassword = $newPassword | ConvertTo-SecureString -asPlainText -Force
$UPN= $newUsername+"#"+$ADDomainName
Invoke-Command -ComputerName $ADaddress -Credential $domainAdminCredential `
-ScriptBlock {`
param($newUsername, $newUserSecurePassword, $newSamAccountName, $newUserDisplayName, $UPN) `
new-aduser -name $newUsername -AccountPassword $newUserSecurePassword -Enabled $true -SamAccountName $newSamAccountName -DisplayName $newUserDisplayName -UserPrincipalName $UPN -PasswordNeverExpires $true`
} `
-ArgumentList $newUsername, $newUserSecurePassword, $newSamAccountName, $newUserDisplayName, $UPN
Tho problem I get when invoking this script is:
Cannot convert 'System.String' to the type 'System.Nullable`1[System.Boolean]' required by parameter 'PasswordNeverExpires'.
I tried passing 1 instead, passing [bool]$true but the result remains the same. I am new to PS and I'm lost here. Can anyone shine some light on what the problem may be?

Alright, I found what the problem was.
Changed:
-PasswordNeverExpires $true`
to
-PasswordNeverExpires $true `
(added a space after true)

replacing $true with a variable did it for me.
So this:
$command = 'New-CMApplicationDeployment -Name $Name -CollectionName $Col -OverrideServiceWindow $true -Comment $Com -AvailableDateTime $Adt -DeployAction Install -DeployPurpose Available -UserNotification DisplaySoftwareCenterOnly'
Invoke-Expression -Command "& $command"
became:
$t = $true
$command = 'New-CMApplicationDeployment -Name $Name -CollectionName $Col -OverrideServiceWindow $t -Comment $Com -AvailableDateTime $Adt -DeployAction Install -DeployPurpose Available -UserNotification DisplaySoftwareCenterOnly'
Invoke-Expression -Command "& $command"
Its dumb but it worked.

Related

switch user "su -" equivalent in Powershell? [duplicate]

I won't get into all the details of why I need this, but users must be able to launch PowerShell as a service account and when PowerShell loads it needs to run a script. I already can launch PowerShell with the stored credentials (stored as a secure string), but for the life of me I cannot get the script (located in $args) to run. I have tried a variety of things, and below is where I am currently. Any help would be greatly appreciated.
$user = "domain\service.account"
$pwd1 = "big long huge string of characters"
$pwd = ($pwd1 | ConvertTo-SecureString)
$Credential = New-Object System.Management.Automation.PSCredential $user, $pwd
$args = "\\domain.local\location\location\location\Script\script.ps1"
Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")
You can open a new powershell window under a specified user credential like this:
start powershell -credential ""
I found this worked for me.
$username = 'user'
$password = 'password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process Notepad.exe -Credential $credential
Updated: changed to using single quotes to avoid special character issues noted by Paddy.
Here's also nice way to achieve this via UI.
0) Right click on PowerShell icon when on task bar
1) Shift + right click on Windows PowerShell
2) "Run as different user"
Try adding the RunAs option to your Start-Process
Start-Process powershell.exe -Credential $Credential -Verb RunAs -ArgumentList ("-file $args")
In windows server 2012 or 2016 you can search for Windows PowerShell and then "Pin to Start". After this you will see "Run as different user" option on a right click on the start page tiles.
You can get a credential popup that will get the username and password as strings like this:
#Get credentials
$credential = Get-Credential
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
Then you can use in your script the variables $username and $password
This command works for me:
Start-Process powershell.exe -Credential $Credential -ArgumentList "-file $FILE"
If the $FILE is on network, make sure the run-as user can access the file.
Script
I just created a script to make it easier for automation:
<#
.SYNOPSIS
Run command as another user.
.DESCRIPTION
Run batch or PowerShell command as another user.
.PARAMETER Command
The batch command you'd like to execute as another user.
.PARAMETER ScriptBlock
The PowerShell command you'd like to execute as another user.
.PARAMETER Username
Run the command as what user.
.PARAMETER Password
Password of the user.
.PARAMETER Credential
PowerShell credential of the user, it can be generated by `Get-Credential`.
.PARAMETER Wait
Wait command to complete or not.
Command output would not be displayed if it is not specified.
#>
Param (
[Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "bat-credential")]
[ValidateNotNullOrEmpty()]
[String]
$Command,
[Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-credential")]
[ScriptBlock]
$ScriptBlock,
[Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
[ValidateNotNullOrEmpty()]
[String]
$Username,
[Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
[ValidateNotNullOrEmpty()]
[String]
$Password,
[Parameter(Mandatory = $true, ParameterSetName = "bat-credential")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-credential")]
[PSCredential]
$Credential,
[Switch]
$Wait
)
$IsCurrentAdminUser = $([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')
# Find a dir that every user have full access to
$TempDir = "$env:SystemDrive\Users\Public\run_as"
if (-not (Test-Path -Path $TempDir)) {
$null = New-Item -Path $TempDir -ItemType Directory
attrib +h $TempDir
}
# Generate a uniq id for problem tracking
$ExecId = Get-Random -Maximum 99999999 -Minimum 10000000
# Temp files
$UserScriptPrefix = "$TempDir\$ExecId-UserScript"
$UserStdOut = "$TempDir\$ExecId-UserStdOut.log"
$UserErrOut = "$TempDir\$ExecId-UserErrOut.log"
$WaitFile = "$TempDir\$ExecId-Running"
$ExecScript = "$TempDir\$ExecId-Exec.ps1"
$CmdToExec = "Start-Process"
if ($PsCmdlet.ParameterSetName.StartsWith('bat')) {
$UserScript = $UserScriptPrefix + '.bat'
$Command |Out-File -FilePath $UserScript -Encoding ascii
$CmdToExec += " cmd.exe -ArgumentList '/c $UserScript'"
} elseif ($PsCmdlet.ParameterSetName.StartsWith('ps')) {
$UserScript = $UserScriptPrefix + '.ps1'
$ScriptBlock |Out-File -FilePath $UserScript -Encoding ascii
$CmdToExec += " PowerShell.exe -ArgumentList '-file $UserScript'"
}
if ($PsCmdlet.ParameterSetName.EndsWith('user-password')) {
$SecPassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential ($Username, $SecPassword)
}
$CmdToExec += " -WorkingDirectory $env:SystemDrive\"
if ($Wait) {
# Redirect output only if -Wait flag is set
$CmdToExec += " -RedirectStandardError $UserErrOut"
$CmdToExec += " -RedirectStandardOutput $UserStdOut"
if ($IsCurrentAdminUser) {
# -Wait parameter of Start-Process only works with admin users
# Using it with non-admin users will get an "Access is denied" error
$CmdToExec += " -Wait"
}
}
$script = #'
Param($Cred)
"" | Out-File -FilePath {0}
try {{
{1} -Credential $Cred
}} catch {{
Write-Host $_
}} finally {{
Remove-Item -Path {0} -Force -Confirm:$false
}}
'# -f $WaitFile, $CmdToExec
$Script |Out-File -FilePath $ExecScript -Encoding ascii
try {
& $ExecScript -Cred $Credential
} catch {
Write-Host $_
} finally {
if ($Wait) {
if (-not $IsCurrentAdminUser) {
# Impelment the wait by file monitoring for non-admin users
do {
Start-Sleep -Seconds 1
} while (Test-Path -Path $WaitFile)
# Wait output are write to files completely
Start-Sleep -Seconds 1
}
# Read command output from files
if (Test-Path -Path $UserStdOut) {
Get-Content -Path $UserStdOut
}
if (Test-Path -Path $UserErrOut) {
Get-Content -Path $UserErrOut
}
}
Remove-Item -Path "$TempDir\$ExecId-*" -Force -Confirm:$false -ErrorAction SilentlyContinue
}
Copy the content and save to a *.ps1 file, like run_as.ps1.
Document
Show build-in doucment:
PS C:\> Get-Help C:\run_as.ps1 -detailed
NAME
C:\run_as.ps1
SYNOPSIS
Run command as another user.
SYNTAX
C:\run_as.ps1 -Command <String> -Credential <PSCredential> [-Wait] [<CommonParameters>]
C:\run_as.ps1 -Command <String> -Username <String> -Password <String> [-Wait] [<CommonParameters>]
C:\run_as.ps1 -ScriptBlock <ScriptBlock> -Credential <PSCredential> [-Wait] [<CommonParameters>]
C:\run_as.ps1 -ScriptBlock <ScriptBlock> -Username <String> -Password <String> [-Wait] [<CommonParameters>]
DESCRIPTION
Run batch or PowerShell command as another user.
PARAMETERS
......
Examples
01
Current user is administrator, run batch command as user01 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
PS C:\> whoami
test-win-1\administrator
PS C:\> .\run_as.ps1 -Command 'whoami' -Username 'user01' -Password 'password1'
PS C:\>
PS C:\> # Add -Wait to get command output
PS C:\> .\run_as.ps1 -Command 'whoami' -Username 'user01' -Password 'password1' -Wait
C:\>whoami
test-win-1\user01
PS C:\>
PS C:\> # Add '#' to batch command to avoid the header lines
PS C:\> .\run_as.ps1 -Command '#whoami' -Username 'user01' -Password 'password1' -Wait
test-win-1\user01
PS C:\>
02
Current user is administrator, run PowerShell command as user02 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
PS C:\> $env:USERPROFILE
C:\Users\Administrator
PS C:\> .\run_as.ps1 -ScriptBlock {$env:USERPROFILE} -Username 'user02' -Password 'password2' -Wait
C:\Users\user02
PS C:\>
03
Current user is administrator, run PowerShell command as user02 with its credential
PS C:\> $env:USERPROFILE
C:\Users\Administrator
PS C:\> $cred = Get-Credential user02 # input user02's password in the pop-up window
PS C:\> .\run_as.ps1 -ScriptBlock {$env:USERPROFILE} -Credential $cred -Wait
C:\Users\user02
PS C:\>
04
Current user is user01, run PowerShell command as administrator
PS C:\> $(Get-ChildItem C:\Users\Administrator\).FullName
Get-ChildItem : Access to the path 'C:\Users\Administrator' is denied.
At line:1 char:3
+ $(Get-ChildItem C:\Users\Administrator\).FullName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Users\Administrator\:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
PS C:\> whoami
test-win-1\user01
PS C:\> # Standard user cannot access administrator user's home directory
PS C:\>
PS C:\> .\run_as.ps1 -ScriptBlock {$(Get-ChildItem C:\Users\Administrator\).FullName} -Username Administrator -Password 'adminpasswd' -Wait
C:\Users\Administrator\.vscode
C:\Users\Administrator\3D Objects
C:\Users\Administrator\Contacts
C:\Users\Administrator\Desktop
C:\Users\Administrator\Documents
C:\Users\Administrator\Downloads
C:\Users\Administrator\Favorites
C:\Users\Administrator\Links
C:\Users\Administrator\Music
C:\Users\Administrator\Pictures
C:\Users\Administrator\Saved Games
C:\Users\Administrator\Searches
C:\Users\Administrator\Videos
PS C:\>
This worked for me. This is helpful in remote servers where you just a have remote command line tool available to use.
runas /user:Administrator "powershell Start-Transcript -Path C:\Users\m\testlog.txt;import-module 'C:\Users\m\script.ps1';Stop-Transcript"
This will also ensure that you can get the output of the command in testlog.txt

Powershell Invoke-Expression A parameter cannot be found that matches parameter name = ""

Im trying to invoke a Ps script from antoher script. The scripts are both in the same path.
Also the script I'm trying to invoke takes 4 parameters.
Whem i execute that file from powershell with the parameters, then it works without errors.
But invoking it with the Invoke-Expression Command does not work.
Keep getting the error :
'A parameter cannot be found that matches parameter name'
Script with the Paramters :
param ([Parameter(Mandatory = $true)]
[string] $Samname,
[string] $Fullname,
[string] $Password,
[string] $Groups
)
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force
New-localuser -name $Samname -FullName $Fullname -password $securePassword -PasswordNeverExpires -UserMayNotChangePassword
#Add the User to the Groups
$localGroups = Get-LocalGroup
[string[]]$GroupArray = $Groups.Split(' ')
foreach ($localgroup in $localGroups){
foreach ($group in $GroupArray){
$group = $group.Replace(';', '')
if ($group.toString().Equals($localgroup.toString())){
Add-LocalGroupMember -Group $localgroup -Member $samname
}
}
}
Script with Invoke-Expression command :
$XmlDocument = 'C:\SomeFile\toPs\TmpUser.config'
[XML]$XmlFile = Get-Content $XmlDocument
[string] $Samname = $XmlFile.User.Username
[string] $Fullname = $XmlFile.User.Fullname
[string] $Password = $XmlFile.User.Password
[string] $Groups = $XmlFile.User.Groups
$script = ".\CreateUser.ps1"
Invoke-Expression $script "-Samname $Samname -Fullname $Fullname -Password $Password -Groups $Groups"
I'm not that sure if I'm using the params the right way, when I invoke the script.
Thanks for your help :)
It's hard to tell exactly what's tripping up Invoke-Expression without the full extent of the error message, but the good news is that you don't need Invoke-Expression at all!
Use the invocation operator (also known as the "call operator", &) instead, it natively supports parameter binding:
$XmlDocument = 'C:\SomeFile\toPs\TmpUser.config'
[XML]$XmlFile = Get-Content $XmlDocument
[string] $Samname = $XmlFile.User.Username
[string] $Fullname = $XmlFile.User.Fullname
[string] $Password = $XmlFile.User.Password
[string] $Groups = $XmlFile.User.Groups
$script = ".\CreateUser.ps1"
& $script -Samname $Samname -Fullname $Fullname -Password $Password -Groups $Groups

Powershell - Retrieve List of Groups, Use List To Find Specific Group Member

Good afternoon. So I have the below line of code that retrieves any AD group with the suffix of -blah1 and blah2.
import-module activedirectory
$group = Get-ADGroup -Filter { (name -like "*-blah1") -or (name -like "*-blah2") } | Select Name
The above code shows groups:
abc-blah1
abc-blah2
I want to be able to query these groups for a specific user (for example: blahuser). If the user does not exist in the group, I want to script to tell me. Any ideas? Thanks.
You are looking for Get-ADGroupMember and a Where-Object command.
Get-ADGroup -Filter { (name -like "*-blah1") -or (name -like "*-blah2") } |
Get-ADGroupMember |
Where-Object {$_.SamAccountName -match 'blahuser'}
Function Connect-Mstsc {
<#
.SYNOPSIS
Function to connect an RDP session without the password prompt
.DESCRIPTION
This function provides the functionality to start an RDP session without having to type in the password
.PARAMETER ComputerName
This can be a single computername or an array of computers to which RDP session will be opened
.PARAMETER User
The user name that will be used to authenticate
.PARAMETER Password
The password that will be used to authenticate
.PARAMETER Credential
The PowerShell credential object that will be used to authenticate against the remote system
.PARAMETER Admin
Sets the /admin switch on the mstsc command: Connects you to the session for administering a server
.PARAMETER MultiMon
Sets the /multimon switch on the mstsc command: Configures the Remote Desktop Services session monitor layout to be identical to the current client-side configuration
.PARAMETER FullScreen
Sets the /f switch on the mstsc command: Starts Remote Desktop in full-screen mode
.PARAMETER Public
Sets the /public switch on the mstsc command: Runs Remote Desktop in public mode
.PARAMETER Width
Sets the /w: parameter on the mstsc command: Specifies the width of the Remote Desktop window
.PARAMETER Height
Sets the /h: parameter on the mstsc command: Specifies the height of the Remote Desktop window
.NOTES
Name: Connect-Mstsc
Author: Jaap Brasser
DateUpdated: 2016-10-28
Version: 1.2.5
Blog: http://www.jaapbrasser.com
.LINK
http://www.jaapbrasser.com
.EXAMPLE
. .\Connect-Mstsc.ps1
Description
This command dot sources the script to ensure the Connect-Mstsc function is available in your current PowerShell session
.EXAMPLE
Connect-Mstsc -ComputerName server01 -User contoso\jaapbrasser -Password (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force)
Description
A remote desktop session to server01 will be created using the credentials of contoso\jaapbrasser
.EXAMPLE
Connect-Mstsc server01,server02 contoso\jaapbrasser (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force)
Description
Two RDP sessions to server01 and server02 will be created using the credentials of contoso\jaapbrasser
.EXAMPLE
server01,server02 | Connect-Mstsc -User contoso\jaapbrasser -Password (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force) -Width 1280 -Height 720
Description
Two RDP sessions to server01 and server02 will be created using the credentials of contoso\jaapbrasser and both session will be at a resolution of 1280x720.
.EXAMPLE
server01,server02 | Connect-Mstsc -User contoso\jaapbrasser -Password (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force) -Wait
Description
RDP sessions to server01 will be created, once the mstsc process is closed the session next session is opened to server02. Using the credentials of contoso\jaapbrasser and both session will be at a resolution of 1280x720.
.EXAMPLE
Connect-Mstsc -ComputerName server01:3389 -User contoso\jaapbrasser -Password (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force) -Admin -MultiMon
Description
A RDP session to server01 at port 3389 will be created using the credentials of contoso\jaapbrasser and the /admin and /multimon switches will be set for mstsc
.EXAMPLE
Connect-Mstsc -ComputerName server01:3389 -User contoso\jaapbrasser -Password (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force) -Public
Description
A RDP session to server01 at port 3389 will be created using the credentials of contoso\jaapbrasser and the /public switches will be set for mstsc
.EXAMPLE
Connect-Mstsc -ComputerName 192.168.1.10 -Credential $Cred
Description
A RDP session to the system at 192.168.1.10 will be created using the credentials stored in the $cred variable.
.EXAMPLE
Get-AzureVM | Get-AzureEndPoint -Name 'Remote Desktop' | ForEach-Object { Connect-Mstsc -ComputerName ($.Vip,$.Port -join ':') -User contoso\jaapbrasser -Password (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force) }
Description
A RDP session is started for each Azure Virtual Machine with the user contoso\jaapbrasser and password supersecretpw
.EXAMPLE
PowerShell.exe -Command "& {. .\Connect-Mstsc.ps1; Connect-Mstsc server01 contoso\jaapbrasser (ConvertTo-SecureString 'supersecretpw' -AsPlainText -Force) -Admin}"
Description
An remote desktop session to server01 will be created using the credentials of contoso\jaapbrasser connecting to the administrative session, this example can be used when scheduling tasks or for batch files.
>
[cmdletbinding(SupportsShouldProcess,DefaultParametersetName='UserPassword')]
param (
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[Alias('CN')]
[string[]] $ComputerName,
[Parameter(ParameterSetName='UserPassword',Mandatory=$true,Position=1)]
[Alias('U')]
[string] $User,
[Parameter(ParameterSetName='UserPassword',Mandatory=$true,Position=2)]
[Alias('P')]
[string] $Password,
[Parameter(ParameterSetName='Credential',Mandatory=$true,Position=1)]
[Alias('C')]
[PSCredential] $Credential,
[Alias('A')]
[switch] $Admin,
[Alias('MM')]
[switch] $MultiMon,
[Alias('F')]
[switch] $FullScreen,
[Alias('Pu')]
[switch] $Public,
[Alias('W')]
[int] $Width,
[Alias('H')]
[int] $Height,
[Alias('WT')]
[switch] $Wait
)
begin {
[string]$MstscArguments = ''
switch ($true) {
{$Admin} {$MstscArguments += '/admin '}
{$MultiMon} {$MstscArguments += '/multimon '}
{$FullScreen} {$MstscArguments += '/f '}
{$Public} {$MstscArguments += '/public '}
{$Width} {$MstscArguments += "/w:$Width "}
{$Height} {$MstscArguments += "/h:$Height "}
}
if ($Credential) {
$User = $Credential.UserName
$Password = $Credential.GetNetworkCredential().Password
}
}
process {
foreach ($Computer in $ComputerName) {
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$Process = New-Object System.Diagnostics.Process
# Remove the port number for CmdKey otherwise credentials are not entered correctly
if ($Computer.Contains(':')) {
$ComputerCmdkey = ($Computer -split ':')[0]
} else {
$ComputerCmdkey = $Computer
}
$ProcessInfo.FileName = "$($env:SystemRoot)\system32\cmdkey.exe"
$ProcessInfo.Arguments = "/generic:TERMSRV/$ComputerCmdkey /user:$User /pass:$($Password)"
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
$Process.StartInfo = $ProcessInfo
if ($PSCmdlet.ShouldProcess($ComputerCmdkey,'Adding credentials to store')) {
[void]$Process.Start()
}
$ProcessInfo.FileName = "$($env:SystemRoot)\system32\mstsc.exe"
$ProcessInfo.Arguments = "$MstscArguments /v $Computer"
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Normal
$Process.StartInfo = $ProcessInfo
if ($PSCmdlet.ShouldProcess($Computer,'Connecting mstsc')) {
[void]$Process.Start()
if ($Wait) {
$null = $Process.WaitForExit()
}
}
}
}
}
You can do it like this:
$userName = "ThisIsMyUserName"
$Groups = Get-ADGroup -Filter { (name -like "*-blah1") -or (name -like "*-blah2") } | Where-Object { $userName -notin ($_ | Get-ADGroupMember).SamAccountName} |select -ExpandProperty name

Issues passing credentials to a function Azure Powershell

Hi all I'm trying to pass server login credentials to my 'createSQLServer function but keep hitting the error 'Cannot process argument transformation on parameter 'creds'.userName'' I've tried a lot of different, even tried with a 'param block' but stull stuck. A push in the right direction would be appreciated, cheers.
###### SQL SERVER LOGIN CREDENTIALS
$userName = "aaron"
$password = "Password_1234"
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName, $securePassword
### SQL server names with resource group name appeneded
$server1 = "sqlserver1" + $resGroup
$serVerion = "12.0"
function createSQLserver ([string]$server1,[string]$server2, [string]$server3, [System.Management.Automation.PSCredential]$creds,[string]$server1Location, [string]$server2Location, [string]$server3Location, [string]$resGroup, [string]$serVerion, [string]$userName, [string]$password, [SecureString]$securePassword)
{
#Create server 1(Server A)
<#check to see if server exists - It exists, $continue is created and passed to
if statement to append two random characters to name#>
Write-Host "Creating First SQL Server"
$sqlServer = New-AzureRmSqlServer -ServerName $server1 -SqlAdministratorCredentials $creds -Location $server1Location -ResourceGroupName $resGroup -ServerVersion $serVerion -ErrorVariable continue -ErrorAction SilentlyContinue
if ($continue)
{
do {
$server1 = $server1 + (rand)
$sqlServer = New-AzureRmSqlServer -ServerName $server1 `
-SqlAdministratorCredentials $creds -Location $server1Location `
-ResourceGroupName $resGroup -ServerVersion "12.0" -ErrorVariable continue -ErrorAction SilentlyContinue
}
until(!$continue)
Write-Host 'exists creating new' $server1 'Created'
}else{
Write-Host $server1 ' Created'
}
Start-Sleep -s 2
}
createSQLserver $server1 $username $password $securePassword $creds $server1Location $resGroup $serVerion
You need to use your named parameters!
Here's a snippet of your first few parameters:
...
[string]$server1
,
[string]$server2
,
[string]$server3
,
[System.Management.Automation.PSCredential]$creds
...
And then the ones you're passing in to the function call
createSQLserver $server1 $username $password $securePassword ...
So because you're not using the names of your parameters, they are using their relative ordinal position i.e.
param | value
---------+----------------
$server1 | $server1
$server2 | $username
$server3 | $password
$creds | $securePassword
So what have we learned?
Always use named parameters!
createSQLserver -server1 $server1 -username $username -password $password -securePassword $securePassword
That should sort you out :-)

Running PowerShell as another user, and launching a script

I won't get into all the details of why I need this, but users must be able to launch PowerShell as a service account and when PowerShell loads it needs to run a script. I already can launch PowerShell with the stored credentials (stored as a secure string), but for the life of me I cannot get the script (located in $args) to run. I have tried a variety of things, and below is where I am currently. Any help would be greatly appreciated.
$user = "domain\service.account"
$pwd1 = "big long huge string of characters"
$pwd = ($pwd1 | ConvertTo-SecureString)
$Credential = New-Object System.Management.Automation.PSCredential $user, $pwd
$args = "\\domain.local\location\location\location\Script\script.ps1"
Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")
You can open a new powershell window under a specified user credential like this:
start powershell -credential ""
I found this worked for me.
$username = 'user'
$password = 'password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process Notepad.exe -Credential $credential
Updated: changed to using single quotes to avoid special character issues noted by Paddy.
Here's also nice way to achieve this via UI.
0) Right click on PowerShell icon when on task bar
1) Shift + right click on Windows PowerShell
2) "Run as different user"
Try adding the RunAs option to your Start-Process
Start-Process powershell.exe -Credential $Credential -Verb RunAs -ArgumentList ("-file $args")
In windows server 2012 or 2016 you can search for Windows PowerShell and then "Pin to Start". After this you will see "Run as different user" option on a right click on the start page tiles.
You can get a credential popup that will get the username and password as strings like this:
#Get credentials
$credential = Get-Credential
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
Then you can use in your script the variables $username and $password
This command works for me:
Start-Process powershell.exe -Credential $Credential -ArgumentList "-file $FILE"
If the $FILE is on network, make sure the run-as user can access the file.
Script
I just created a script to make it easier for automation:
<#
.SYNOPSIS
Run command as another user.
.DESCRIPTION
Run batch or PowerShell command as another user.
.PARAMETER Command
The batch command you'd like to execute as another user.
.PARAMETER ScriptBlock
The PowerShell command you'd like to execute as another user.
.PARAMETER Username
Run the command as what user.
.PARAMETER Password
Password of the user.
.PARAMETER Credential
PowerShell credential of the user, it can be generated by `Get-Credential`.
.PARAMETER Wait
Wait command to complete or not.
Command output would not be displayed if it is not specified.
#>
Param (
[Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "bat-credential")]
[ValidateNotNullOrEmpty()]
[String]
$Command,
[Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-credential")]
[ScriptBlock]
$ScriptBlock,
[Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
[ValidateNotNullOrEmpty()]
[String]
$Username,
[Parameter(Mandatory = $true, ParameterSetName = "bat-user-password")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-user-password")]
[ValidateNotNullOrEmpty()]
[String]
$Password,
[Parameter(Mandatory = $true, ParameterSetName = "bat-credential")]
[Parameter(Mandatory = $true, ParameterSetName = "ps-credential")]
[PSCredential]
$Credential,
[Switch]
$Wait
)
$IsCurrentAdminUser = $([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')
# Find a dir that every user have full access to
$TempDir = "$env:SystemDrive\Users\Public\run_as"
if (-not (Test-Path -Path $TempDir)) {
$null = New-Item -Path $TempDir -ItemType Directory
attrib +h $TempDir
}
# Generate a uniq id for problem tracking
$ExecId = Get-Random -Maximum 99999999 -Minimum 10000000
# Temp files
$UserScriptPrefix = "$TempDir\$ExecId-UserScript"
$UserStdOut = "$TempDir\$ExecId-UserStdOut.log"
$UserErrOut = "$TempDir\$ExecId-UserErrOut.log"
$WaitFile = "$TempDir\$ExecId-Running"
$ExecScript = "$TempDir\$ExecId-Exec.ps1"
$CmdToExec = "Start-Process"
if ($PsCmdlet.ParameterSetName.StartsWith('bat')) {
$UserScript = $UserScriptPrefix + '.bat'
$Command |Out-File -FilePath $UserScript -Encoding ascii
$CmdToExec += " cmd.exe -ArgumentList '/c $UserScript'"
} elseif ($PsCmdlet.ParameterSetName.StartsWith('ps')) {
$UserScript = $UserScriptPrefix + '.ps1'
$ScriptBlock |Out-File -FilePath $UserScript -Encoding ascii
$CmdToExec += " PowerShell.exe -ArgumentList '-file $UserScript'"
}
if ($PsCmdlet.ParameterSetName.EndsWith('user-password')) {
$SecPassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential ($Username, $SecPassword)
}
$CmdToExec += " -WorkingDirectory $env:SystemDrive\"
if ($Wait) {
# Redirect output only if -Wait flag is set
$CmdToExec += " -RedirectStandardError $UserErrOut"
$CmdToExec += " -RedirectStandardOutput $UserStdOut"
if ($IsCurrentAdminUser) {
# -Wait parameter of Start-Process only works with admin users
# Using it with non-admin users will get an "Access is denied" error
$CmdToExec += " -Wait"
}
}
$script = #'
Param($Cred)
"" | Out-File -FilePath {0}
try {{
{1} -Credential $Cred
}} catch {{
Write-Host $_
}} finally {{
Remove-Item -Path {0} -Force -Confirm:$false
}}
'# -f $WaitFile, $CmdToExec
$Script |Out-File -FilePath $ExecScript -Encoding ascii
try {
& $ExecScript -Cred $Credential
} catch {
Write-Host $_
} finally {
if ($Wait) {
if (-not $IsCurrentAdminUser) {
# Impelment the wait by file monitoring for non-admin users
do {
Start-Sleep -Seconds 1
} while (Test-Path -Path $WaitFile)
# Wait output are write to files completely
Start-Sleep -Seconds 1
}
# Read command output from files
if (Test-Path -Path $UserStdOut) {
Get-Content -Path $UserStdOut
}
if (Test-Path -Path $UserErrOut) {
Get-Content -Path $UserErrOut
}
}
Remove-Item -Path "$TempDir\$ExecId-*" -Force -Confirm:$false -ErrorAction SilentlyContinue
}
Copy the content and save to a *.ps1 file, like run_as.ps1.
Document
Show build-in doucment:
PS C:\> Get-Help C:\run_as.ps1 -detailed
NAME
C:\run_as.ps1
SYNOPSIS
Run command as another user.
SYNTAX
C:\run_as.ps1 -Command <String> -Credential <PSCredential> [-Wait] [<CommonParameters>]
C:\run_as.ps1 -Command <String> -Username <String> -Password <String> [-Wait] [<CommonParameters>]
C:\run_as.ps1 -ScriptBlock <ScriptBlock> -Credential <PSCredential> [-Wait] [<CommonParameters>]
C:\run_as.ps1 -ScriptBlock <ScriptBlock> -Username <String> -Password <String> [-Wait] [<CommonParameters>]
DESCRIPTION
Run batch or PowerShell command as another user.
PARAMETERS
......
Examples
01
Current user is administrator, run batch command as user01 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
PS C:\> whoami
test-win-1\administrator
PS C:\> .\run_as.ps1 -Command 'whoami' -Username 'user01' -Password 'password1'
PS C:\>
PS C:\> # Add -Wait to get command output
PS C:\> .\run_as.ps1 -Command 'whoami' -Username 'user01' -Password 'password1' -Wait
C:\>whoami
test-win-1\user01
PS C:\>
PS C:\> # Add '#' to batch command to avoid the header lines
PS C:\> .\run_as.ps1 -Command '#whoami' -Username 'user01' -Password 'password1' -Wait
test-win-1\user01
PS C:\>
02
Current user is administrator, run PowerShell command as user02 with password
Note: Please DO NOT use plain password in production environment. You can use it for testing.
In a production environment, you can use -Credential option instead.
PS C:\> $env:USERPROFILE
C:\Users\Administrator
PS C:\> .\run_as.ps1 -ScriptBlock {$env:USERPROFILE} -Username 'user02' -Password 'password2' -Wait
C:\Users\user02
PS C:\>
03
Current user is administrator, run PowerShell command as user02 with its credential
PS C:\> $env:USERPROFILE
C:\Users\Administrator
PS C:\> $cred = Get-Credential user02 # input user02's password in the pop-up window
PS C:\> .\run_as.ps1 -ScriptBlock {$env:USERPROFILE} -Credential $cred -Wait
C:\Users\user02
PS C:\>
04
Current user is user01, run PowerShell command as administrator
PS C:\> $(Get-ChildItem C:\Users\Administrator\).FullName
Get-ChildItem : Access to the path 'C:\Users\Administrator' is denied.
At line:1 char:3
+ $(Get-ChildItem C:\Users\Administrator\).FullName
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Users\Administrator\:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
PS C:\> whoami
test-win-1\user01
PS C:\> # Standard user cannot access administrator user's home directory
PS C:\>
PS C:\> .\run_as.ps1 -ScriptBlock {$(Get-ChildItem C:\Users\Administrator\).FullName} -Username Administrator -Password 'adminpasswd' -Wait
C:\Users\Administrator\.vscode
C:\Users\Administrator\3D Objects
C:\Users\Administrator\Contacts
C:\Users\Administrator\Desktop
C:\Users\Administrator\Documents
C:\Users\Administrator\Downloads
C:\Users\Administrator\Favorites
C:\Users\Administrator\Links
C:\Users\Administrator\Music
C:\Users\Administrator\Pictures
C:\Users\Administrator\Saved Games
C:\Users\Administrator\Searches
C:\Users\Administrator\Videos
PS C:\>
This worked for me. This is helpful in remote servers where you just a have remote command line tool available to use.
runas /user:Administrator "powershell Start-Transcript -Path C:\Users\m\testlog.txt;import-module 'C:\Users\m\script.ps1';Stop-Transcript"
This will also ensure that you can get the output of the command in testlog.txt