

# Use Session Scripts to Manage Your Amazon WorkSpaces Applications Users' Streaming Experience
<a name="use-session-scripts"></a>

WorkSpaces Applications provides on-instance session scripts. You can use these scripts to run your own custom scripts when specific events occur in users' streaming sessions. For example, you can use custom scripts to prepare your WorkSpaces Applications environment before your users' streaming sessions begin. You can also use custom scripts to clean up streaming instances after users complete their streaming sessions. 

Session scripts are specified within an WorkSpaces Applications image. These scripts are run within the user context or the system context. If your session scripts use the standard out to write information, error, or debugging messaging, these can be optionally saved to an Amazon S3 bucket within your Amazon Web Services account.

**Topics**
+ [Run Scripts Before Streaming Sessions Begin](run-scripts-before-streaming-sessions-begin.md)
+ [Run Scripts After Streaming Sessions End](run-scripts-after-streaming-sessions-end.md)
+ [Create and Specify Session Scripts](create-specify-session-scripts.md)
+ [Session Scripts Configuration File](session-script-configuration-file.md)
+ [Using Windows PowerShell Files](using-powershell-files-with-session-scripts.md)
+ [Logging Session Script Output](logging-session-output.md)
+ [Use Storage Connectors with Session Scripts](use-storage-connectors-with-session-scripts.md)
+ [Enable Amazon S3 Bucket Storage for Session Script Logs](enable-S3-bucket-storage-session-script-logs.md)
+ [Use Session Scripts on Multi-Session Fleets](session-scripts-multi-session-fleets.md)

# Run Scripts Before Streaming Sessions Begin
<a name="run-scripts-before-streaming-sessions-begin"></a>

You can configure your scripts to run for a maximum of 60 seconds before your users' applications launch and their streaming sessions begin. Doing so enables you to customize the WorkSpaces Applications environment before users start streaming their applications. When the session scripts run, a loading spinner displays for your users. When your scripts complete successfully or the maximum waiting time elapses, your users' streaming session will begin. If your scripts don't complete successfully, an error message displays for your users. However, your users are not prevented from using their streaming session.

When you specify a file name on a Windows instance, you must use a double backslash. For example:

C:\$1\$1Scripts\$1\$1Myscript.bat

If you don't use a double backslash, an error displays to notify you that the .json file is incorrectly formatted.

**Note**  
When your scripts complete successfully, they must return a value of 0. If your scripts return a value other than 0, WorkSpaces Applications displays the error message to the user. 

When you run scripts before streaming sessions begin and the WorkSpaces Applications dynamic application framework is not enabled, the following process occurs:

![\[WorkSpaces Applications workflow diagram showing connection, application selection, and session launch steps.\]](http://docs.aws.amazon.com/appstream2/latest/developerguide/images/session-scripts-without-DAF-non-domain-joined2.png)


1. Your users connect to an WorkSpaces Applications fleet instance that is not domain-joined. They connect by using one of the following access methods:
   + WorkSpaces Applications user pool
   + SAML 2.0
   + WorkSpaces Applications API

1. The application catalog displays in the WorkSpaces Applications portal, and your users choose an application to launch.

1. One of the following occurs:
   + If application settings persistence is enabled for your users, the application settings Virtual Hard Disk (VHD) file that stores your users' customizations and Windows settings is downloaded and mounted. Windows user login is required in this case.

     For information about application settings persistence, see [Enable Application Settings Persistence for Your WorkSpaces Applications Users](app-settings-persistence.md).
   + If application settings persistence is not enabled, the Windows user is already logged in.

1. Your session scripts start. If persistent storage is enabled for your users, storage connector mounting also starts. For information about persistent storage, see [Enable and Administer Persistent Storage for Your WorkSpaces Applications Users](persistent-storage.md).
**Note**  
The storage connector mount doesn't need to complete for the streaming session to start. If the session scripts complete before the storage connector mount completes, the streaming session starts.   
For information about monitoring the mount status of storage connectors, see [Use Storage Connectors with Session Scripts](use-storage-connectors-with-session-scripts.md).

1. Your session scripts complete or time out.

1. The users' streaming session starts. 

1. The application that your users chose launches.

For information about the WorkSpaces Applications dynamic application framework, see [Use the WorkSpaces Applications Dynamic Application Framework to Build a Dynamic App Provider](build-dynamic-app-provider.md).

When you run scripts before streaming sessions begin and the WorkSpaces Applications dynamic application framework is enabled, the following process occurs:

![\[WorkSpaces Applications workflow from user login to application launch, including SAML authentication and session scripts.\]](http://docs.aws.amazon.com/appstream2/latest/developerguide/images/session-scripts-with-DAF-domain-joined2.png)


1. Your users visit the SAML 2.0 application portal for your organization, and they choose the WorkSpaces Applications stack.

1. They connect to an WorkSpaces Applications fleet instance that is domain-joined.

1. If application settings persistence is enabled for your users, the application settings VHD file that stores your users' customizations and Windows settings is downloaded and mounted.

1. Windows user logon occurs.

1. The application catalog displays in the WorkSpaces Applications portal and your users choose an application to launch.

1. Your session scripts start. If persistent storage is enabled for your users, storage connector mounting also starts.
**Note**  
The storage connector mount doesn't need to complete for the streaming session to start. If the session scripts complete before the storage connector mount completes, the streaming session starts.   
For information about monitoring the mount status of storage connectors, see [Use Storage Connectors with Session Scripts](use-storage-connectors-with-session-scripts.md).

1. Your session scripts complete or time out.

1. The users' streaming session starts.

1. The application that your users chose launches.

# Run Scripts After Streaming Sessions End
<a name="run-scripts-after-streaming-sessions-end"></a>

You can also configure your scripts to run after users' streaming sessions end. For example, you can run a script when users select **End Session** from the WorkSpaces Applications toolbar, or when they reach the maximum allowed duration for the session. You can also use these session scripts to clean up your WorkSpaces Applications environment before a streaming instance is terminated. For example, you can use scripts to release file locks or upload log files. When you run scripts after streaming sessions end, the following process occurs:

![\[Flowchart showing WorkSpaces Applications session termination process with scripts and storage actions.\]](http://docs.aws.amazon.com/appstream2/latest/developerguide/images/session-scripts-termination.png)


1. Your users' WorkSpaces Applications streaming session ends.

1. Your session termination scripts start.

1. The session termination scripts complete or time out.

1. Windows user logout occurs. 

1. One or both of the following occur in parallel, if applicable:
   + If application settings persistence is enabled for your users, the application settings VHD file that stores your users' customizations and Windows settings is unmounted and uploaded to an Amazon S3 bucket in your account.
   + If persistent storage is enabled for your users, the storage connector completes a final synchronization and is unmounted.

1. The fleet instance is terminated.

# Create and Specify Session Scripts
<a name="create-specify-session-scripts"></a>

You can configure and specify session scripts for Always-on, On-demand, and Elastic fleets.

**To configure and specify session scripts for Always-on and On-demand fleets**

1. Open the WorkSpaces Applications console at [https://console.aws.amazon.com/appstream2](https://console.aws.amazon.com/appstream2).

1. In the navigation pane, choose **Images**, **Image Builder**.

1. Choose an image builder that is in the **Running** state, and choose **Connect**.

1. When prompted, choose **Administrator**.

1. Navigate to `C:\AppStream\SessionScripts`, and open the `config.json` configuration file.

   For information about session script parameters, see [Session Scripts Configuration File](session-script-configuration-file.md).

1. After you finish making your changes, save and close the `config.json` file.

1. On the image builder desktop, open **Image Assistant**.

1. (Optional) Specify any additional applications that you want to include in the image.

1. Follow the necessary steps in Image Assistant to finish creating your image.

   If the session scripts configuration can't be validated (for example, if the .json file is not correctly formatted), you are notified when you choose **Disconnect and create image**. 
**Note**  
To locate the session scripts configuration file for Linux-based image builders, navigate to `/opt/appstream/SessionScripts/config.json`.

**To configure and specify session scripts for Elastic fleets**

1. Create a zip file that contains the session scripts and config.json file. The scripts files will be copied to the following locations. You must use these locations for your config.json. 
   + For Windows, use `C:\AppStream\SessionScripts\SessionScript`.
   + For Linux, use `/opt/appstream/SessionScripts/SessionScript`.
**Note**  
In order to run the session script files, make sure that the .zip file only contains the session scripts and `config.json` files, and not the containing folder. For more information, see [Session Scripts Configuration File](session-script-configuration-file.md).

1. Upload the zip file to an Amazon S3 bucket in your account.
**Note**  
Your VPC must provide access to the Amazon S3 bucket. For more information, see [Using Amazon S3 VPC Endpoints for WorkSpaces Applications Features](managing-network-vpce-iam-policy.md).  
You must have your S3 bucket and WorkSpaces Applications fleet in the same AWS Region.  
You must have IAM permissions to perform the `S3:GetObject` action on the session scripts object in the Amazon S3 bucket. To learn more about storing the session scripts in an Amazon S3 bucket, see [Store Application Icon, Setup Script, Session Script, and VHD in an S3 Bucket](store-s3-bucket.md).

1. Open the WorkSpaces Applications console at [https://console.aws.amazon.com/appstream2](https://console.aws.amazon.com/appstream2).

1. In the navigation pane, choose **Fleets**.

1. Choose an Elastic fleet that you want to update, and then choose **View Details**.

1. On the **Session scripts settings** tab, choose **Edit**.

1. For **Session scripts object in S3**, either enter the S3 URI that represents the session scripts object, or choose **Browse S3** to navigate to your S3 buckets and find the session scripts object.

1. After you finish making your changes, choose **Save Changes**.

1. At this point, session scripts are available for all fleet instances launched.
**Note**  
You can also configure the session scripts when you create a new Elastic fleet. 

# Session Scripts Configuration File
<a name="session-script-configuration-file"></a>

To locate the session scripts configuration file in a Windows instance, navigate to C:\$1AppStream\$1SessionScripts\$1config.json. On a Linux instance, navigate to /opt/appstream/SessionScripts/config.json. The file is formatted as follows.

**Note**  
The configuration file is in .json format. Verify that any text you type in this file is in valid .json format.

```
{
  "SessionStart": {
    "executables": [
      {
        "context": "system",
        "filename": "",
        "arguments": "",
        "s3LogEnabled": true
      },
      {
        "context": "user",
        "filename": "",
        "arguments": "",
        "s3LogEnabled": true
      }
    ],
    "waitingTime": 30
  },
  "SessionTermination": {
    "executables": [
      {
        "context": "system",
        "filename": "",
        "arguments": "",
        "s3LogEnabled": true
      },
      {
        "context": "user",
        "filename": "",
        "arguments": "",
        "s3LogEnabled": true
      }
    ],
    "waitingTime": 30
  }
}
```

You can use the following parameters in the session scripts configuration file.

***SessionStart/SessionTermination ***  
The session scripts to run in the appropriate session event based on the name of the object.   
**Type**: String  
**Required**: No  
**Allowed values:** **SessionStart**, **SessionTermination**

***WaitingTime***  
The maximum duration of the session scripts in seconds.  
**Type**: Integer  
**Required**: No  
**Constraints:** The maximum duration is 60 seconds. If the session scripts don't complete within this duration, they will be stopped. If you require a script to continue running, launch it as a separate process.

***Executables***  
The details for the session scripts to run.  
**Type**: String  
**Required**: Yes  
**Constraints:** The maximum number of scripts that can run per session event is 2 (one for the user context, one for the system context).

***Context***  
The context in which to run the session script.   
**Type**: String  
**Required**: Yes  
**Allowed values:** **user**, **system**

***Filename***  
The full path to the session script to run. If this parameter is not specified, the session script is not run.   
**Type**: String  
**Required**: No  
**Constraints:** The maximum length for the file name and full path is 1,000 characters.  
**Allowed values:** **.bat**, **.exe**, **.sh**  
You can also use Windows PowerShell files. For more information, see [Using Windows PowerShell Files](using-powershell-files-with-session-scripts.md).

***Arguments***  
The arguments for your session script or executable file.  
**Type**: String  
**Required**: No  
**Length constraints:** The maximum length is 1,000 characters.

***S3LogEnabled***  
When the value for this parameter is set to **True**, an S3 bucket is created within your Amazon Web Services account to store the logs created by the session script. By default, this value is set to **True**. For more information, see the *Logging Session Script Output* section later in this topic.   
**Type**: Boolean  
**Required**: No  
**Allowed values:** **True**, **False**

# Using Windows PowerShell Files
<a name="using-powershell-files-with-session-scripts"></a>

To use Windows PowerShell files, specify the full path to the PowerShell file in the **filename** parameter:

```
"filename": 
"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
```

Then specify your session script in the **arguments** parameter:

```
"arguments": "-File \"C:\\path\\to\\session\\script.ps1\"",
```

Finally, verify that the PowerShell Execution Policy allows your PowerShell file to run.

# Logging Session Script Output
<a name="logging-session-output"></a>

When this option is enabled in the configuration file, WorkSpaces Applications automatically captures the output from the session script that is written to the standard out. This output is uploaded to an Amazon S3 bucket in your account. You can review the log files for troubleshooting or debugging purposes. 

**Note**  
The log files are uploaded when the session script returns a value, or the value set in **WaitingTime** has elapsed, whichever comes first.

# Use Storage Connectors with Session Scripts
<a name="use-storage-connectors-with-session-scripts"></a>

When WorkSpaces Applications storage connectors are enabled, they begin mounting when the session start scripts run. If your script relies on the storage connectors being mounted, you can wait for the connectors to be available. WorkSpaces Applications maintains the mount status of the storage connectors in the Windows registry on Windows instances, at the following key:

HKEY\$1LOCAL\$1MACHINE\$1SOFTWARE\$1Amazon\$1AppStream\$1Storage\$1<provided user name>\$1<Storage connector>

The registry key values are as follows:
+ Provided user name — The user ID provided through the access mode. The access modes and value for each mode are as follows:
  + User Pool — The email address for the user
  + Streaming URL — The UserID
  + SAML — The NameID. If the user name includes a slash (for example, a domain user’s SAMAccountName), the slash is replaced by a "-" character.
+ Storage connector — The connector for the persistent storage option that is enabled for the user. The storage connector values are as follows:
  + HomeFolder
  + GoogleDrive
  + OneDrive

Each storage connector registry key contains a **MountStatus** DWORD value. The following table lists the possible values for **MountStatus**.

**Note**  
To view these registry keys, you must have Microsoft .NET Framework version 4.7.2 or later installed on your image.


| Value | Description | 
| --- | --- | 
| 0 |  Storage connector not be enabled for this user  | 
| 1 |  Storage connector mounting is in progress  | 
| 2 |  Storage connector mounted successfully  | 
| 3 |  Storage connector mounting failed  | 
| 4 |  Storage connector mounting is enabled, but not mounted yet  | 

On Linux instances, you can check the home folder mount status by looking at the value of appstream\$1home\$1folder\$1mount\$1status in the file \$1/.config/appstream-home-folder/appstream-home-folder-mount-status.


| Value | Description | 
| --- | --- | 
| True |  Home folder is mounted successfully  | 
| False | Home folder is not mounted yet | 

# Enable Amazon S3 Bucket Storage for Session Script Logs
<a name="enable-S3-bucket-storage-session-script-logs"></a>

When you enable Amazon S3 logging in your session script configuration, WorkSpaces Applications captures standard output from your session script. The output is periodically uploaded to an S3 bucket within your Amazon Web Services account. For every AWS Region, WorkSpaces Applications creates a bucket in your account that is unique to your account and the Region.

You do not need to perform any configuration tasks to manage these S3 buckets. They are fully managed by the WorkSpaces Applications service. The log files that are stored in each bucket are encrypted in transit using Amazon S3's SSL endpoints and at rest using Amazon S3-managed encryption keys. The buckets are named in a specific format as follows:

```
appstream-logs-region-code-account-id-without-hyphens-random-identifier
```

***region-code***  
This is the AWS Region code in which the stack is created with Amazon S3 bucket storage enabled for session script logs.

***account-id-without-hyphens***  
Your Amazon Web Services account identifier. The random ID ensures that there is no conflict with other buckets in that Region. The first part of the bucket name, `appstream-logs`, does not change across accounts or Regions.

For example, if you specify session scripts in an image in the US West (Oregon) Region (us-west-2) on account number 123456789012, WorkSpaces Applications creates an Amazon S3 bucket within your account in that Region with the name shown. Only an administrator with sufficient permissions can delete this bucket.

```
appstream-logs-us-west-2-1234567890123-abcdefg
```

Disabling session scripts does not delete any log files stored in the S3 bucket. To permanently delete log files, you or another administrator with adequate permissions must do so by using the Amazon S3 console or API. WorkSpaces Applications adds a bucket policy that prevents accidental deletion of the bucket. For more information, see *IAM Policies and the Amazon S3 Bucket for Application Settings Persistence* in [Identity and Access Management for Amazon WorkSpaces Applications](controlling-access.md).

When session scripts are enabled, a unique folder is created for each streaming session that is started. 

 The path for the folder where the log files are stored in the S3 bucket in your account uses the following structure:

```
bucket-name/stack-name/fleet-name/access-mode/user-id-SHA-256-hash/session-id/SessionScriptsLogs/session-event
```

***bucket-name***  
The name of the S3 bucket in which the session scripts are stored. The name format is described earlier in this section.

***stack-name***  
The name of the stack the session came from.

***fleet-name***  
The name of the fleet the session script is running on.

***access-mode***  
The identity method of the user: `custom` for the WorkSpaces Applications API or CLI, `federated` for SAML, and `userpool` for users in the user pool.

***user-id-SHA-256-hash***  
The user-specific folder name. This name is created using a lowercase SHA-256 hash hexadecimal string generated from the user identifier.

***session-id***  
The identifier of the user's streaming session. Each user streaming session generates a unique ID.

***session-event***  
The event that generated the session script log. The event values are: `SessionStart` and `SessionTermination`.

The following example folder structure applies to a streaming session started from the test-stack and test-fleet. The session uses the API of user ID `testuser@mydomain.com`, from an AWS account ID of `123456789012`, and the settings group `test-stack` in the US West (Oregon) Region (us-west-2):

```
appstream-logs-us-west-2-1234567890123-abcdefg/test-stack/test-fleet/custom/a0bcb1da11f480d9b5b3e90f91243143eac04cfccfbdc777e740fab628a1cd13/05yd1391-4805-3da6-f498-76f5x6746016/SessionScriptsLogs/SessionStart/
```

This example folder structure contains one log file for a user context session start script, and one log file for a system context session start script, if applicable.

# Use Session Scripts on Multi-Session Fleets
<a name="session-scripts-multi-session-fleets"></a>

When using session scripts on multi-session fleets, there are additional requirements and considerations to ensure optimal performance and security.

## Requirements
<a name="session-scripts-multi-session-fleets-requirements"></a>

On a single-session fleet, for a given instance, the **SessionStart** and **SessionTermination** hooks are guaranteed to run only one time. This is because there is a 1:1 mapping of sessions to instances. When using multi-session fleets, there is an N:M mapping of sessions to instances, where each session runs its own **SessionStart** and **SessionTermination** hook. This means that the **SessionStart** and **SessionTermination** hooks can be run many times on a given instance, and in many different orderings. For the best experience, the following should be true of your session scripts when used on multi-session fleets:
+ Scripts are idempotent.

  When an action has already been performed, scripts should handle more than one execution on the same instance with graceful handling.
+ Scripts are independent.

  Because scripts run per session, if one session is running **SessionTermination** while another is running **SessionStart**, they should not interfere with each other, or with the experience of other sessions.
+ Scripts are performant.

  On multi-session instances, multiple sessions can be provisioned concurrently. This means that there can be multiple concurrent executions of the session scripts. Scripts should be efficient, not consume excessive resources, and not impact the experience of other users on the instance or the stability of the sessions.

Many of these requirements can be met by keeping session script logic focused on the specific user session for which the script is running. 

## Security Considerations
<a name="session-scripts-multi-session-fleets-security"></a>

WorkSpaces Applications images should not be configured to allow write permission to session script files by any users. This introduces a critical attack vector for malicious users, where they could modify script files. These files could then be run as SYSTEM or another user, depending on your configuration.

**Important**  
It is your responsibility to make sure that your WorkSpaces Applications images are configured securely. This is especially important for multi-session instances, where multiple users are using the same instance. If images are not configured securely, there is a security risk for all users of that instance.

The following should be true of your images and session scripts files:
+ Users do not have permission to modify session script files.
+ Users do not have permission to modify the session script config.json. Default behavior on the image restricts access to administrators.

Session scripts executables should be stored in a secure location where they are safe from modification at runtime.

If the service detects that a session script executable has been modified, it will fail any subsequent executions of that hook on that instance, upload log files to Amazon S3 (if Amazon S3 logging is enabled), and you will see the following message:

**The session script was not executed because the executable was modified after instance provisioning. Execution was skipped for security.**

If your use case requires modifying the session script executable at run time (for example, if you point to an EXE file which is modified by an automatic update process at runtime), this will fail the above checks. In this case, use a script to redirect execution to your modified executable. Leave the script unmodified at runtime when the service performs security checks.

If your session script files are excessively large (more than 100 MB), this can cause delays in instance and session provisioning, and the security checks will take additional time (depending on instance type and available resources). If your use case requires large session scripts, consider using smaller scripts to redirect execution. This will improve instance and session provisioning experiences.

Note that the service is only checking the executable defined in the session scripts config.json, and this is only a fallback/best effort mechanism. It is your responsibility to ensure that all code paths in session scripts executables are secure and cannot be modified by end users.