Reputation: 657
I have a following function, which displays a credential window as follows.
File: popup.ps1
(This is not a psm. Just a script with only popup()
)
function popup
{
[CmdletBinding()]
param(
[Parameter (Mandatory=$True)]
[string] $username
)
$credential = Get-Credential -Username $username -Message "Provide Credentials"
$pass = $credential.GetNetworkCredential().password
}
Now, if this ps1 is sourced in a PowerShell console and execute popup()
command, the credentials pop-up is not shown. However, if I wrap this function by a calling script and execute (i.e. right click → Run with PowerShell) I'm able to see the GUI pop-up.
File: wrapper.ps1
. "./popup.ps1"
$uname = "viswa-ksp"
popup -username $uname
Could anyone explain me why GUI not shown when ran from PowerShell console, however when executed as a script? Am I missing something here?
EDIT :
It was actually a bug from my side. Fellow developer had commented the sourcing part . <path to the cmdlet source>
as part of his debugging / troubleshooting for a different issue and I have overseen it. However thought mentally that the sourcing is still there ( since I know I had included the sourcing ).
Thanks for your valuable comments. Since more than 2 people said not reproducible, I again went and read the script once-again and found this issue.
But here is the follow-up question. I know that for cmdlet you will have to source it. But I want to understand, why nothing is happening if you just run the cmdlet without sourcing it. No error No pop-up. I even tested the return code. It is empty.
PS C:\Users\kspviswa\Desktop> .\popup.ps1
PS C:\Users\kspviswa\Desktop> $ret = .\popup.ps1
PS C:\Users\kspviswa\Desktop> Write-Host $ret
PS C:\Users\kspviswa\Desktop>
Would anybody explain this behaviour?
Upvotes: 1
Views: 853
Reputation: 3053
The reason why nothing returned after running the script without dot-sourcing is , the script is not throwing any output. save this as a script and run without dot-sourcing
function popup
{
[CmdletBinding()]
param(
[Parameter (Mandatory=$True)]
[string] $username
)
write-host "String Inside function"
$credential = Get-Credential -Username $username -Message "Provide Credentials"
$credential.GetNetworkCredential().password
}
write-host "String outside Function but inside the script"
The output must be String outside Function but inside the script
try it by dot-sourcing
PS >. .\script.ps1
PS >String outside Function but inside the script
PS >popup -username USERNAME
PS >String Inside function
And if you don't dot-source the script, the function will get defined and removed after the script executes as the scope of the function is inside the script by default
and if you dot-source it will load function into memory.
If you change the scope of the function as global, you can use it without dot-sourcing
function global: popup
{
[CmdletBinding()]
param(
[Parameter (Mandatory=$True)]
[string] $username
)
write-host "String Inside function"
$credential = Get-Credential -Username $username -Message "Provide Credentials"
$credential.GetNetworkCredential().password
}
write-host "String outside Function but inside the script"
You can run the script without dot sourcing open a new PowerShell console and try this
PS >.\script.ps1
PS >String outside Function but inside the script
PS >popup -username USERNAME
PS >String Inside function
more about scopes https://technet.microsoft.com/en-us/library/hh847849.aspx
Best regards,
kvprasoon
Upvotes: 1
Reputation: 200373
Your function doesn't return the password because you assign it to a variable instead of actually returning it. Change this line:
$pass = $credential.GetNetworkCredential().password
into this:
$credential.GetNetworkCredential().password
Also, running a script doesn't automatically call any function defined in it. A function definition just makes the function available in the scope in which the script is executed. Dot-sourcing loads the script in the current scope, so you can use the function in your console after dot-sourcing the script. If you run the script it is executed in a child scope, so you'd need to explicitly call the function in the child scope to invoke its functionality. See about_Scopes
and the dot-sourcing section of about_Scripts
Upvotes: 1