PowerShell (.ps1) Scripting
  • 20 Oct 2023
  • 4 Minutes to read
  • Dark
    Light
  • PDF

PowerShell (.ps1) Scripting

  • Dark
    Light
  • PDF

Article summary

PowerShell is the standard for automating configuration on Windows servers, and Otter was designed to seamlessly integrate with it -- whether that means running your existing scripts across dozens of servers, leveraging scripts built by the community, or a custom combination of both.

While you definitely don't need to be a scripting guru to use Otter, learning how to incorporate scripts into Otter will enable you to automate virtually any aspect of Windows, at the click of a button.

Adding Existing Scripts to Otter

The easiest way to add your existing scripts to Otter is by navigating to Scripts > Add Script, and then creating or uploading your scripts. You can also add scripts and assets directly to a Git repository that you've configured as a Git-based raft, and Otter will use your repository instead.

Running PowerShell Scripts on Servers

Otter can create a GUI for your scripts so that it becomes easy to run complex PowerShell scripts by defining script parameters that include descriptions, help text, dropdown, or checkbox inputs, and more.

The best way to do this is creating a Job Template that runs your script against target servers. You can also use an ad-hoc Job to run the script without a template.

See the Create a GUI for Scripts with Input Forms for step-by-step guide on this in Otter.

Note:

By default, PowerShell will prefer using Windows PowerShell 5.1 when available. Starting with v2.4.0 of the Scripting extensions, this functionality can be changed to prefer PowerShell Core by setting the configuration value $PreferWindowsPowerShell to false. This can be set globally at the extension/system level or scoped to a server, environment, job, etc...

If you are executing PowerShell from OtterScript, all the PowerShell operations have a PreferWindowsPowerShell parameter that can be set also. This parameter will default to use $PreferWindowsPowerShell.

Using OtterScript to Orchestration Scripts

Once you've added PowerShell Scripts to Otter, you can use an OtterScript Orchestration to run those scripts on different servers in a complex manner, whether that means targeting servers sequentially, in parallel, or even with branching and iterating (looping) logic.

Although OtterScript is based on programming logic, you do not need to be a coder to use OtterScript, which offers both a text editor and a low-code visual editor.

Using PSCall to Run PowerShell

You can call your scripts using the PSCall Operation. If you use PowerShell's Comment-based Help, you'll get descriptions for script arguments when editing in visual mode, similar to running the script using a Job.

pscall CreateUserInDirectory(
  domain: hdars.local,
  user: $UserName
);

pscall GiveUserPermissions(
  domain: hdars.local,
  user: $UserName
);

Collecting & Verifying with PowerShell

Otter can use your existing PowerShell scripts to verify server configuration by using a special operation called PSVerify. This leverages PowerShell's Comment-based Help and adds "Augmented-Help Blocks" to help instruct Otter on how to verify desired configuration.

See Compliance as Code with PowerShell & PSVerify to learn more.

PowerShell Script Asset

<# 
.PARAMETER HotFixID
ID of the HotFix to check, such as "KB4562830"

.AHCONFIGTYPE
HotFix

.AHCONFIGKEY 
$HotFixID
#>
param ([string]$HotFixID)

if (!(Get-HotFix -Id  $HotFixID) 2> $null){
    Write-Warning "HotFixID $HotFixID is not installed"
    return $false;
}
return $true;

OtterScript Desired Configuration

PSVerify verify-hotfix-installed
(
  HotFixID: KB4532938
);

PSVerify verify-hotfix-installed
(
  HotFixID: KB4483843
);

Remedating Drift with PowerShell

In addition to verifying the configuration of your servers, Otter can use your existing PowerShell scripts to reconfigure your servers into your desired state using an operation called PSEnsure.

This is a bit different than PowerShell's Desired State Configuration (DSC), and it's a simpler alternative that lets you use basic PowerShell commands.

See the Remediating Drift with PowerShell & PSEnsure to learn more.

PowerShell Script ASset

<# 
.AHEXECMODE 
$ExecutionMode
#>

if ($ExecutionMode = "Collect") {
    if (-not(Get-Hotfix -Id $KB)) {
        Write-Information "HotFixID KB4532938 is not installed."
        return $false
    } 
    else {
        Write-Information "HotFixID KB4532938 is installed."
        return $true
        }
    } 
elseif ($ExecutionMode = "Configure") { 
    if (-not(Get-Hotfix -Id $KB)) {
        Start-Process -FilePath "wusa.exe" -ArgumentList "KB4532938.msu /quiet /norestart" -Wait 
    } 
    else {
        Write-Information "HotFixID KB4532938 is already installed."
    }
}

Using PowerShellDSC with OtterScript

PowerShell Desired State Configuration (DSC) offers quite a few open-source modules that you can use to configure different features of Windows Servers. With PSDsc, you can invoke DSC Resources in nearly the same manner as a native DSC statement.

PSDsc xWebAppPool (
  Name: AccountsAppPool,
  Ensure: present
);

These declarative-style statements are essentially Ensure Operations, and thus will collect, report, and remediate drift just like the Built-in Operations.

Inline Execution of PowerShell

Through PSExec and Swim Strings, you can run scripts text directly from your OtterScript.

Otter will seamlessly replace variables within this script string, so in the example below $ApplicationName might be defined as a Configuration Variable.

PSExec Example

psexec >>
  # delete all but the latest 3 logs in the log directory
  Get-ChildItem "E:\Site\Logs\$ApplicationName" |
     Sort-Object $.CreatedDate -descending |
     Select-Object -skip 3 |
     Remove-Item
>>;

Evaluating PowerShell Literals

OtterScript is not a general-purpose programming language, and thus doesn't have built-in support for things like arithmetic. You could, of course, write a custom variable function to support this, but PSEval is much easier:

For example, if you wanted to convert the value stored in one variable ($minutes) to milliseconds. You could PSEval the simple expression $minutes * 60 * 1000:

set $milliseconds = $PSEval($minutes * 60 * 1000);

$PSEval runs the expression on the server currently in context, so use it inside of an If/Else Block to perform different operations depending on the results of the expression on that server.


Was this article helpful?