devblogs.microsoft.com
Open in
urlscan Pro
2a02:26f0:480:b9e::2f1e
Public Scan
URL:
https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/
Submission: On October 18 via api from US — Scanned from DE
Submission: On October 18 via api from US — Scanned from DE
Form analysis
3 forms found in the DOMName: searchForm — GET /search
<form class="c-search" autocomplete="off" id="searchForm" name="searchForm" role="search" action="/search" method="GET"
data-seautosuggest="{"queryParams":{"market":"en-us","clientId":"7F27B536-CF6B-4C65-8638-A0F8CBDFCA65","sources":"Microsoft-Terms,Iris-Products,DCatAll-Products","filter":"+ClientType:StoreWeb","counts":"5,1,5"},"familyNames":{"Apps":"App","Books":"Book","Bundles":"Bundle","Devices":"Device","Fees":"Fee","Games":"Game","MusicAlbums":"Album","MusicTracks":"Song","MusicVideos":"Video","MusicArtists":"Artist","OperatingSystem":"Operating System","Software":"Software","Movies":"Movie","TV":"TV","CSV":"Gift Card","VideoActor":"Actor"}}"
data-seautosuggestapi="https://www.microsoft.com/msstoreapiprod/api/autosuggest"
data-m="{"cN":"GlobalNav_Search_cont","cT":"Container","id":"c1c9c3m1r1a1","sN":1,"aN":"c9c3m1r1a1"}" aria-expanded="false" style="overflow-x: visible;">
<div class="x-screen-reader" aria-live="assertive"></div>
<input id="cli_shellHeaderSearchInput" aria-label="Search Expanded" aria-autocomplete="list" aria-expanded="false" aria-controls="universal-header-search-auto-suggest-transparent" aria-owns="universal-header-search-auto-suggest-ul" type="search"
name="query" role="combobox" placeholder="Search" data-m="{"cN":"SearchBox_nav","id":"n1c1c9c3m1r1a1","sN":1,"aN":"c1c9c3m1r1a1"}" data-toggle="tooltip" data-placement="right"
title="" data-original-title="Search" style="overflow-x: visible;">
<input type="hidden" name="blog" value="/powershell/" data-m="{"cN":"HiddenInput_nav","id":"n2c1c9c3m1r1a1","sN":2,"aN":"c1c9c3m1r1a1"}" style="overflow-x: visible;">
<button id="search" aria-label="Search" class="c-glyph" data-m="{"cN":"Search_nav","id":"n3c1c9c3m1r1a1","sN":3,"aN":"c1c9c3m1r1a1"}" data-bi-mto="true" aria-expanded="false"
style="overflow-x: visible;">
<span role="presentation" style="overflow-x: visible;">Search</span>
<span role="tooltip" class="c-uhf-tooltip c-uhf-search-tooltip" style="overflow-x: visible;">Search</span>
</button>
<div class="m-auto-suggest" id="universal-header-search-auto-suggest-transparent" role="group" style="overflow-x: visible;">
<ul class="c-menu" id="universal-header-search-auto-suggest-ul" aria-label="Search Suggestions" aria-hidden="true" data-bi-dnt="true" data-bi-mto="true" data-js-auto-suggest-position="default" role="listbox" data-tel="jsll"
data-m="{"cN":"search suggestions_cont","cT":"Container","id":"c4c1c9c3m1r1a1","sN":4,"aN":"c1c9c3m1r1a1"}" style="overflow-x: visible;"></ul>
<ul class="c-menu f-auto-suggest-no-results" aria-hidden="true" data-js-auto-suggest-postion="default" data-js-auto-suggest-position="default" role="listbox" style="overflow-x: visible;">
<li class="c-menu-item" style="overflow-x: visible;"> <span tabindex="-1" style="overflow-x: visible;">No results</span></li>
</ul>
</div>
</form>
POST https://devblogs.microsoft.com/powershell?na=s
<form method="post" action="https://devblogs.microsoft.com/powershell?na=s" onsubmit="return newsletter_check(this)">
<input type="hidden" name="nlang" value="">
<div class="col-8 tnp-field tnp-field-email pull-left" style="margin-right:13px;width: 300px;margin-left: 30px;"><input style="border: 1px solid #CED4DA;background-color:#FFF;height: 34px;font-size: 14px;" class="tnp-email x-hidden-focus"
type="email" name="ne" placeholder="Enter your email" required=""></div>
<div style="padding:0 10px;" class="tnp-field tnp-field-button"><input style="background-color: #0072cc;padding: 6px 20px;height: 32px;font-size: 14px;" class="tnp-submit x-hidden-focus" type="submit" value="Subscribe">
<div style="clear: both;"></div>
<div class="tnp-field tnp-privacy-field"><label style="font-size: 14px;font-weight: normal;">By subscribing you agree to our <a href="https://docs.microsoft.com/en-us/collaborate/terms-of-use" target="_blank">Terms of Use</a> and
<a href="https://privacy.microsoft.com/en-us/privacystatement" target="_blank">Privacy Policy</a></label></div>
</div>
</form>
#
<form id="myForm" action="#">
<div class="modal-body">
<div class="form-group">
<label for="code-text">Paste your code snippet</label>
<textarea class="form-control" id="code-text" style="height: 150px;"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" onclick="myCodeCancelFunction()" class="btn btn-primary" data-dismiss="modal">Cancel</button>
<button type="button" onclick="myCodeFunction()" class="btn btn-primary">Ok</button>
</div>
</form>
Text Content
Skip to main content Microsoft Powershell Team Powershell Team Powershell Team * Home * DevBlogs * Developer * Visual Studio * Visual Studio Code * Visual Studio for Mac * DevOps * Windows Developer * Developer support * ISE Developer * Engineering@Microsoft * Azure SDK * IoT * Command Line * Perf and Diagnostics * Dr. International * Notification Hubs * Math in Office * React Native * Technology * DirectX * PIX * Semantic Kernel * SurfaceDuo * Startups * Sustainable Engineering * Windows AI Platform * Languages * C++ * C# * F# * Visual Basic * TypeScript * PowerShell Community * PowerShell Team * Python * Q# * JavaScript * Java * Java Blog in Chinese * .NET * All .NET posts * .NET MAUI * ASP.NET Core * Blazor * Entity Framework * ML.NET * NuGet * Servicing * Xamarin * .NET Blog in Chinese * Platform Development * #ifdef Windows * Azure Depth Platform * Azure Government * Azure VM Runtime Team * Bing Dev Center * Microsoft Edge Dev * Microsoft Azure * Microsoft 365 Developer * Microsoft Entra Identity Developer Blog * Old New Thing * Power Platform * Windows MIDI and Music dev * Windows Search Platform * Data Development * Azure Cosmos DB * Azure Data Studio * Azure SQL Database * OData * Revolutions R * SQL Server Data Tools * More Theme * Light * Dark Login Search Search * No results Cancel Email Subscriptions are here! Get notified in your email when a new post is published to this blog Subscribe Close POWERSHELL CONSTRAINED LANGUAGE MODE PowerShell Team November 2nd, 20173 0 POWERSHELL CONSTRAINED LANGUAGE MODE UPDATE (MAY 17, 2018) In addition to the constraints listed in this article, system wide Constrained Language mode now also disables the ScheduledJob module. The ScheduledJob feature uses Dot Net serialization that is vulnerable to deserialization attacks. So now whenever an application whitelisting solution is applied such as DeviceGuard or AppLocker, PowerShell will run in Constrained Language mode and also disable the ScheduledJob module. Use the Windows Task Scheduler or PowerShell ScheduledTasks module as an alternative. For more information see CVE-2018-0958. WHAT IS POWERSHELL CONSTRAINED LANGUAGE? PowerShell Constrained Language is a language mode of PowerShell designed to support day-to-day administrative tasks, yet restrict access to sensitive language elements that can be used to invoke arbitrary Windows APIs. You can place a PowerShell session into Constrained Language mode simply by setting a property: PS C:\> $ExecutionContext.SessionState.LanguageMode FullLanguage PS C:\> $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" PS C:\> $ExecutionContext.SessionState.LanguageMode ConstrainedLanguage PS C:\> [System.Console]::WriteLine("Hello") Cannot invoke method. Method invocation is supported only on core types in this language mode. At line:1 char:1 + [System.Console]::WriteLine("Hello") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage Of course, this is not secure. A user can simply start another PowerShell session which will run in Full Language mode and have full access to PowerShell features. As part of the implementation of Constrained Language, PowerShell included an environment variable for debugging and unit testing called __PSLockdownPolicy. While we have never documented this, some have discovered it and described this as an enforcement mechanism. This is unwise because an attacker can easily change the environment variable to remove this enforcement. In addition, there are also file naming conventions that enable FullLanguage mode on a script, effectively bypassing Constrained Language. Again, this is for unit testing. These test hooks cannot override a Device Guard UMCI policy and can only be used when no policy enforcement is applied. THEN WHAT IS IT FOR? PowerShell Constrained Language mode was designed to work with system-wide application control solutions such as Device Guard User Mode Code Integrity (UMCI). Application control solutions are an incredibly effective way to drastically reduce the risk of viruses, ransomware, and unapproved software. For DeviceGuard UMCI the approved applications are determined via a UMCI policy. PowerShell automatically detects when a UMCI policy is being enforced on a system and will run only in Constrained Language mode. So PowerShell Constrained Language mode becomes more interesting when working in conjunction with system-wide lockdown policies. PowerShell’s detection of system policy enforcement through DeviceGuard is supported only for Windows platform running Windows PowerShell version 5.1 or PowerShell 7. It does not work on non-Windows platforms. So this is currently very much a Windows security feature. However, we will continue to enhance this for non-Windows platforms where feasible. These lockdown policies are important for high-value systems that need to be protected against malicious administrators or compromised administrator credentials. With a policy enforced even administrators are limited to what they can do on the system. Since Constrained Language is so limited, you will find that many of the approved scripts that you use for advanced systems management no longer work. The solution to this is simple: add these scripts (or more effectively: your code signing authority that signed them) to your Device Guard policy. This will allow your approved scripts to run in Full Language mode. For example, all PowerShell module files shipped with Windows (e.g., Install-WindowsFeature) are trusted and signed. The UMCI policy allowing signed Windows files lets PowerShell run these modules in Full Language mode. But if you create a custom PowerShell module that is not allowed by the policy then it will be considered untrusted and run with Constrained Language restrictions. Consequently, any PowerShell module marked as trusted in the policy needs to be carefully reviewed for security vulnerabilities. A vulnerability could allow code injection, or leak private functions not intended for public use. In either case it could allow a user to run arbitrary code in Full Language mode, thus bypassing the system policy protections. We have described these dangers in much more detail in our post, “Writing Secure PowerShell Scripts” (coming soon). WHAT DOES CONSTRAINED LANGUAGE CONSTRAIN? Constrained Language consists of a number of restrictions that limit unconstrained code execution on a locked-down system. These restrictions are: * PowerShell module script files must explicitly export functions by name without the use of wildcard characters. This is to prevent inadvertently exposing powerful helper function not meant to be used publicly. * PowerShell module manifest files must explicitly export functions by name without the use of wildcards. Again, to prevent inadvertent exposure of functions. * COM objects are blocked. They can expose Win32 APIs that have likely never been rigorously hardened as part of an attack surface. * Only approved .NET types are allowed. Many .NET types can be used to invoke arbitrary Win32 APIs. As a result only specific whitelisted types are allowed. * Add-Type is blocked. It allows the creation of arbitrary types defined in different languages. * The use of PowerShell classes are disallowed. PowerShell classes are just arbitrary C# type definitions. * PowerShell type conversion is not allowed. Type conversion implicitly creates types and runs type constructors. * Dot sourcing across language modes is disallowed. Dot sourcing a script file brings all functions, variables, aliases from that script into the current scope. So this blocks a trusted script from being dot sourced into an untrusted script and exposing all of its internal functions. Similarly, an untrusted script is prevented from being dot sourced into a trusted script so that it cannot pollute the trusted scope. * Command resolution automatically hides commands you cannot run. For example, a function created in Constrained Language mode is not visible to script running in Full Language mode. * XAML based workflows are blocked since they cannot be constrained by PowerShell. But script based workflows and trusted XAML based workflows shipped in-box are allowed. * The SupportedCommand parameter for Import-LocalizedData is disabled. It allows additional commands prevented by Constrained Language. * Invoke-Expression cmdlet always runs in Constrained Language. Invoke-Expression cannot validate input as trusted. * Set-PSBreakpoint command is blocked unless there is a system-wide lockdown through UMCI. * Command completers are always run in Constrained Language. Command completers are not validated as trustworthy. * Commands and script run within the script debugger will always be run in Constrained Language if there is a system-wide lockdown. * The DSC Configuration keyword is disabled. * Supported commands and Statements are not allowed in script DATA sections. * Start-Job is unavailable if the system is not locked-down. Start-Job starts PowerShell in a new process and if the system is not locked-down the new process runs in Full Language mode. As we can see, Constrained Language mode imposes some significant restrictions on PowerShell. Nevertheless, it remains a formidable and capable shell and scripting language. You can run native commands and PowerShell cmdlets and you have access to the full scripting features: variables, statements, loops, functions, arrays, hashtables, error handling, etc. HOW IS THIS DIFFERENT FROM JEA? PowerShell Constrained Language restricts only some elements of the PowerShell language along with access to Win32 APIs. It provides full shell access to all native commands and many cmdlets. It is not designed to operate independently and needs to work with application control solutions such as UMCI to fully lockdown a system and prevent access to unauthorized applications. Its purpose is to provide PowerShell on a locked-down system without compromising the system. JEA (Just Enough Administration) is a sandboxed PowerShell remote session that is designed to strictly limit what the logged on user can do. It is configured in ‘no language mode’, has no access to file or other drive providers, and makes only a small set of cmdlets available. These cmdlets are often custom and designed to perform specific management functions without giving unfettered access to the system. The set of cmdlets provided in the session is role based (RBAC) and the session can be run in virtual or Group Managed Service accounts. The JEA scenario is where an administrator needs to perform a management task on a high-value machine (such as collect logs or restart a specific service). The administrator creates a remote PowerShell session to the machine’s JEA endpoint. Within that session the user has access to only those commands needed to perform the task and cannot directly access the file system or the registry or run arbitrary code. SUMMARY PowerShell Constrained Language is designed to work with application whitelisting solutions in order to restrict what can be accessed in an interactive PowerShell session with policy enforcement. You configure which scripts are allowed full system access through the whitelisting solution policy. In contrast, JEA is a sandboxed PowerShell remote session that restricts an interactive session to specific commands based on user role. Paul Higinbotham [MSFT] PowerShell Team POWERSHELL TEAM POWERSHELL TEAM, POWERSHELL Follow READ NEXT Azure Automation DSC Pricing Flexibility Today we would like to share a new flexible pricing strategy for managing server nodes using Azure Automation to deliver PowerShell Desired State Configuration, giving ... Michael Greene November 14, 2017 0 comment DSC Resource Kit Release November 2017 We just released the DSC Resource Kit! This release includes updates to 10 DSC resource modules. In these past 6 weeks, 53 pull requests have been merged and 50 ... Katie Keim [MSFT] November 15, 2017 0 comment 3 COMMENTS Comments are closed. Login to edit/delete your existing comments * Artem Pronichkin June 2, 2019 11:09 am 1 collapse this comment copy link to this comment > We have described these dangers in much more detail in our post, “Writing Secure PowerShell Scripts” (coming soon). so, it’s been over a year already. Was it ever published? Where is it? if not, maybe it’s time to remove this announcement * Anthony Yates November 19, 2019 7:28 am 0 collapse this comment copy link to this comment I realise this is old, but I am looking for a definition of what “Script Enforcement” does in Windows Defender Application Control. It certainly puts PowerShell into Constrained Language mode. BUT where is the logic for what scripts are allowed to run? This blog post says that signed scripts can run. But does that depend on WDAC allowing those signer certificates? And, if it does, then does that mean that any means of authorisising a script, not just certificates, also allows the script to run in Full Language mode? * Shurinbaal Addamasartus April 19, 2020 9:34 pm 0 collapse this comment copy link to this comment constrained mode is useless when it comes to confidence of security…. dont rely on it RELEVANT LINKS * PowerShell on GitHub * PowerShell Documentation TOP BLOGGERS Sydney Smith PM Steven Bucher Product Manager Jason Helmick PROGRAM MANAGER 2 Steve Lee Jim Truher Senior Software Engineer ARCHIVE October 2023 September 2023 August 2023 July 2023 June 2023 May 2023 March 2023 February 2023 January 2023 December 2022 November 2022 October 2022 September 2022 August 2022 July 2022 June 2022 May 2022 March 2022 February 2022 January 2022 December 2021 November 2021 October 2021 August 2021 July 2021 June 2021 May 2021 April 2021 March 2021 February 2021 January 2021 December 2020 November 2020 October 2020 September 2020 August 2020 July 2020 June 2020 May 2020 April 2020 March 2020 February 2020 December 2019 November 2019 October 2019 September 2019 August 2019 July 2019 June 2019 May 2019 April 2019 March 2019 February 2019 January 2019 November 2018 October 2018 September 2018 August 2018 July 2018 June 2018 May 2018 April 2018 March 2018 February 2018 January 2018 December 2017 November 2017 October 2017 September 2017 August 2017 July 2017 June 2017 May 2017 April 2017 March 2017 February 2017 January 2017 December 2016 November 2016 October 2016 September 2016 August 2016 July 2016 June 2016 May 2016 April 2016 March 2016 February 2016 January 2016 December 2015 November 2015 October 2015 September 2015 August 2015 July 2015 June 2015 May 2015 April 2015 February 2015 December 2014 November 2014 October 2014 September 2014 August 2014 July 2014 June 2014 May 2014 April 2014 March 2014 February 2014 January 2014 December 2013 November 2013 October 2013 August 2013 July 2013 June 2013 April 2013 March 2013 January 2013 December 2012 October 2012 September 2012 August 2012 July 2012 June 2012 May 2012 April 2012 March 2012 February 2012 January 2012 December 2011 October 2011 September 2011 August 2011 July 2011 June 2011 May 2011 April 2011 March 2011 February 2011 January 2011 December 2010 November 2010 October 2010 September 2010 July 2010 June 2010 May 2010 April 2010 March 2010 February 2010 January 2010 December 2009 November 2009 October 2009 September 2009 August 2009 July 2009 June 2009 May 2009 April 2009 March 2009 February 2009 January 2009 December 2008 November 2008 October 2008 September 2008 August 2008 July 2008 June 2008 May 2008 April 2008 March 2008 February 2008 January 2008 December 2007 November 2007 October 2007 September 2007 August 2007 July 2007 June 2007 May 2007 April 2007 March 2007 February 2007 January 2007 December 2006 November 2006 October 2006 September 2006 August 2006 July 2006 June 2006 May 2006 April 2006 November 2001 STAY INFORMED By subscribing you agree to our Terms of Use and Privacy Policy * * * CODE BLOCK × Paste your code snippet Cancel Ok Feedback What's new * Surface Laptop Studio 2 * Surface Laptop Go 3 * Surface Pro 9 * Surface Laptop 5 * Surface Studio 2+ * Copilot in Windows * Microsoft 365 * Windows 11 apps Microsoft Store * Account profile * Download Center * Microsoft Store support * Returns * Order tracking * Certified Refurbished * Microsoft Store Promise * Flexible Payments Education * Microsoft in education * Devices for education * Microsoft Teams for Education * Microsoft 365 Education * How to buy for your school * Educator training and development * Deals for students and parents * Azure for students Business * Microsoft Cloud * Microsoft Security * Dynamics 365 * Microsoft 365 * Microsoft Power Platform * Microsoft Teams * Microsoft Industry * Small Business Developer & IT * Azure * Developer Center * Documentation * Microsoft Learn * Microsoft Tech Community * Azure Marketplace * AppSource * Visual Studio Company * Careers * About Microsoft * Company news * Privacy at Microsoft * Investors * Diversity and inclusion * Accessibility * Sustainability California Consumer Privacy Act (CCPA) Opt-Out Icon Your Privacy Choices California Consumer Privacy Act (CCPA) Opt-Out Icon Your Privacy Choices * Sitemap * Contact Microsoft * Privacy * Manage cookies * Terms of use * Trademarks * Safety & eco * Recycling * About our ads * © Microsoft 2023