I cant for the life of me figure out how to save the current PowerShell script to a specific location on a client so I can create a scheduled task to execute it on log on. The script is being run from intune. So after it runs I need to save it to Program data and be able to call it.
something along the lines of copy "`$PSCommandPath:" to c:\programdata\script
if ($PSCommandPath -eq $null) { function GetPSCommandPath() { return $MyInvocation.PSCommandPath; } $PSCommandPath = GetPSCommandPath; }
function PSCommandPath() { return $PSCommandPath; }
function ScriptName() { return $MyInvocation.ScriptName; }
function MyCommandName() { return $MyInvocation.MyCommand.Name; }
function MyCommandDefinition() {
# Begin of MyCommandDefinition()
# Note: ouput of this script shows the contents of this function, not the
execution result
return $MyInvocation.MyCommand.Definition;
# End of MyCommandDefinition()
}
function MyInvocationPSCommandPath() { return
$MyInvocation.PSCommandPath; }
Write-Host "`$PSCommandPath:";
Write-Host " * Direct: $PSCommandPath";
Write-Host " * Function: $(PSCommandPath)";
Thanks in advance.
Related
How do I call methods within workflow?
I am trying to call "Task" from within a workflow and it seems to be getting ignored? I have provided a watered down nonsense code to illustrate what I'm trying to do. basically call a method within the class in parallel and return the results.
Sample Code
Class Something {
[string]Task($item) {
Start-sleep -Seconds 10
Return "Result"
}
[System.Array]GetSomething($list) {
workflow GetWF {
param($listarr)
ForEach -parallel ($item in $listarr) {
$res = InlineScript {
Write-Host("Starting.." + $using:item)
$this.Task($using:item)
}
}
$res
}
Return GetWF -listarr $list
}
}
$list = #('host1','host2','host3','host4')
$Something = [Something]::New()
$Something.GetSomething($list)
Output :
Starting..host1
Starting..host4
Starting..host2
Starting..host3
Desired Result from Example
The issue is how do I get my results back as an array ? In this example above I would like to see the final result to be this:
$Result = #("Result","Result","Result","Result")
I am working on implementing a singleton class to store some regularly accessed status information for my script, including hacking around the issue of $myInvocation only being populated in the main script. All working as planned with this.
class pxStatus {
static [pxStatus] $singleton = $null
[string]$Context = 'machine'
[string]$Path = $null
[datetime]$StartTime = (Get-Date)
pxStatus ([string]$path) {
if ([pxStatus]::singleton -eq $null) {
$this.Path = $path
[pxStatus]::singleton = $this
} else {
Throw "Singleton already initialized"
}
}
static [pxStatus] Get() {
if ([pxStatus]::singleton -eq $null) {
Throw "Singleton not yet initialized"
} else {
return [pxStatus]::singleton
}
}
}
CLS
[void]([pxStatus]::New((Split-Path ($myInvocation.myCommand.path) -parent)))
([pxStatus]::Get()).StartTime
([pxStatus]::Get()).Context
([pxStatus]::Get()).Path
With one exception. Even with that [void] on the [pxStatus]::New() line, I am getting a blank line in the console. Even $null = ([pxStatus]::New((Split-Path ($myInvocation.myCommand.path) -parent))) is echoing a blank line to the console. And for the life of me I can't see what is causing it.
It's not new that causes a blank line but ([pxStatus]::Get()).StartTime.
To fix the issue, you may output it as string, i.e. not formatted, e.g. ([pxStatus]::Get()).StartTime.ToString()
You problem has already been diagnosed, but I wanted to take a second to show how to actually implement a singleton-like type in PowerShell (see inline comments):
class pxStatus {
# hide backing field from user
hidden static [pxStatus] $singleton = $null
[string]$Context = 'machine'
[string]$Path = $null
[datetime]$StartTime = (Get-Date)
# hide instance constructor, no one should call this directly
hidden pxStatus ([string]$path) {
# Only allow to run if singleton instance doesn't exist already
if ($null -eq [pxStatus]::singleton) {
$this.Path = $path
} else {
Throw "Singleton already initialized - use [pxStatus]::Get()"
}
}
# Use a static constructor to initialize singleton
# guaranteed to only run once, before [pxStatus]::Get() or [pxStatus]::singleton
static pxStatus () {
# grab the path from context, don't rely on user input
if(-not $PSScriptRoot){
throw "[pxStatus] can only be used in scripts!"
}
# this will only succeed once anyway
[pxStatus]::singleton = [pxStatus]::new($PSScriptRoot)
}
static [pxStatus] Get() {
# No need to (double-)check ::singleton, static ctor will have run already
return [pxStatus]::singleton
}
}
[pxStatus]::Get().StartTime
I have a quick powershell syntax question. I have following loop in powershell. I would like to know which value exists (which is easy). I can use either "Read" or "Visitor" to assign permission. I can do 2 if statements but if there is a smarter way i would rather use that.
if(($listRA.Member.Name) -ne $authUsers)
{
foreach($spRoleDefinition in $rc)
{
if(($spRoleDefinition.Name -eq "Read") -OR ($spRoleDefinition.Name -eq "SP Visitor"))
{
Need to determine which one exists
Adding a user code....
write-host $spRoleDefinition.Name
}
}
}
Use a switch statement:
if(($listRA.Member.Name) -ne $authUsers)
{
foreach($spRoleDefinition in $rc)
{
switch($spRoleDefinition.Name)
{
'Read' {
# do Read stuff
break;
}
'SP Visitor' {
# do SP Visitor stuff
break;
}
}
}
}
I need to execute the following script:
Get-MailboxDatabase -Status | select ServerName,Name,DatabaseSize
I tried a few solutions with Powershell and Command classes, but they doesn't work.
Error that I received:
Value parameters cannot be null.
I think this will do what you're looking for:
private string RunLocalExchangePowerShell(string script)
{
// create the runspace and load the snapin
RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
Runspace runSpace = RunspaceFactory.CreateRunspace(rsConfig);
runSpace.Open();
rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapInException);
Pipeline pipeLine = runSpace.CreatePipeline();
// load the script and convert the output to a string
pipeLine.Commands.AddScript(script);
pipeLine.Commands.Add("out-string");
// get the results
Collection<PSObject> results;
results = pipeLine.Invoke();
// loop through the results and build the output
StringBuilder sb = new StringBuilder();
foreach (PSObject obj in results)
{
sb.AppendLine(obj.ToString());
}
// close the pipeline and runspace
pipeLine.Dispose();
runSpace.Close();
return sb.ToString();
}
Example usage:
Console.WriteLine(prog.RunLocalExchangePowerShell("Get-MailboxDatabase -Status | select ServerName,Name,DatabaseSize"));
From a PS script, I am calling a primalforms dialog box err.ps1, but I don't know how to return to the main script which button the users clicked on err.ps1 (Yes/No).
if (.{.\errDestination.ps1})
Doesn't seem to return the value being true as yes or false as no...
Any idea where should I set the return result?
You have to edit the generated code a bit to return the DialogResult. I put this at the bottom:
#endregion Generated Form Code
# ....
#Show the Form
$form1.ShowDialog()| Out-Null
return $form1.DialogResult
} #End Function
#Call the Function
return GenerateForm
#endregion
To evaluate it form the calling script:
$result = & .\errDestination.ps1
if ($result -eq "Yes") {
# Yes
} else {
# No
}