Posted in ActiveDirectory, CLI, Powershell

Get-ACL for a Computer Object

Just a quick post as I ran into something that really had me confused.  I have used get-acl and set-acl for folders and files, very frequently and easily actually.  Researching an SCCM issue, a scripting task presented itself.  A list of all computers and whether or not the “Windows Authorization Access Group” is listed in the Security for the object.  Using AD Users and Computers, you have to use View\Advanced Features, and then inspect the Security tab for the computer object.  I wrote a quick loop and on one machine it was producing verifiable results while on another machine the results were consistently negative results.

Versions of Powershell are the same, the ActiveDirectory module is the same… hmmmmm what is the difference?  “pwd” revealed the culprit.  What is odd, with my other ACL operations I did not specifiy that the current location is AD:\ but in order for get-acl $machine.DistinguishedName  to work and not return object not found I have to ensure get-location returns AD:\

Advertisements
Posted in Module, Plaster, Powershell

Plaster Baby Steps

Just a quick note… started to get addicted to plaster. One other thing I learned but not fully. I wanted to include the PowerShell Version to the plaster process. I made changes and the template started failing. It would appear there is some case sensitivity:

powerShellVersion='$PLASTER_PARAM_ModulePSVer'
The “p” in powerShellVersion appears to be lowercase only. I have to figure out the parameter names and case sensitivity. I found this by trial and error but I need to get more fluent with it.
Posted in Module, Plaster, Powershell

PowerShell Plaster Baby Steps

I have created modules, normally just for a demo showing how easy it would be to distribute PowerShell. They were simply a script I renamed to psm1 or a psm1 I created and threw some functions in it.

With the current role in, I see a greater need for a few modules. I could go with a bunch of functions in a script, or load scripts during runtime of my main script. I do not want to clutter my script with a large number of functions or even a few lines like:

. .\script1.ps1
. .\script2.ps1

Now I have to admit I have use Sapien’s PowerShell Studio to create a few modules. While I love the product I do not have access to it. That said it creates basic/static module files.

I saw the plaster module, read a few articles about it and at first my response was “meh” but hey it is prompting me for some interesting items so I must be missing something. I spent a day or two but just couldn’t figure something out like adding the Company Name at build time.

I was using Twitter to follow the news coming from the 2018 PowerShell summit. A post announced that there was going to be a presentation regarding Plaster. I liked the post and mentioned that I can’t wait to see the presentation when it was posted.

Two days later I received a link to the presentation. Major thanks to  for facilitating @rjpleau sending me a link to the presentation materials which can be found on github here.

Using this as a practical reference I was able to figure out what I was doing wrong with just get the company name as a runtime option. I know, nothing monumental but I write my own modules but at work I want to ensure I record my employers company name.

Sorry for the formatting of the XML is not great. Basically I copied an existing template (finding that folder is not easy (start looking in $env:userprofile either .vscode or .vscode-insiders then find the powershell module, then modules folder then plaster and then the templates folder). I copied the NewPowerShellScriptModule then renamed it. Then I edited the plastermanifest.xml to what you see below.

<?xml version="1.0" encoding="utf-8"?>
<plasterManifest
    schemaVersion="1.1"
    templateType="Project" xmlns="http://www.microsoft.com/schemas/PowerShell/Plaster/v1">
    <metadata>
        <name>JJK</name>
        <id>dd02bf66-9960-4014-a6fc-f09d5387c189</id>
        <version>1.0.0</version>
        <title>JJK Module Template</title>
        <description>Customized Manifest for creating Modules</description>
        <author>Kavanagh</author>
        <tags>Automation</tags>
    </metadata>
        <parameters>
                <parameter name="ModuleFullName" type="text" prompt="Module author's name" />
                <parameter name="ModuleName" type="text" prompt="Name of your module" />
                <parameter name="ModuleDesc" type="text" prompt="Brief description on this module" />
                <parameter name="Version" type="text" prompt="Initial module version" default="0.0.1" />
                <parameter name="ModuleCompanyName" type="text" prompt="Company name" default='N/A' />
                <parameter name="ModuleScripts" type="choice" prompt="Create a scripts folder for non function scripts?" default='1'>
                        <choice label="&amp;Yes" help="Creates a en-US folder within the module root" value="Yes" />
                        <choice label="&amp;No" help="Does not create a en-US folder within the module root" value="No" />
                </parameter>
        </parameters>
    <content>
        <message>

Scaffolding your PowerShell Module...


</message>
                <newModuleManifest destination='${PLASTER_PARAM_ModuleName}.psd1'
                                                     author = '$PLASTER_PARAM_ModuleFullName'
                                                     moduleVersion='$PLASTER_PARAM_Version'
                                                     rootModule='${PLASTER_PARAM_ModuleName}.psm1'
                                                     companyName='$PLASTER_PARAM_ModuleCompanyName'
                                                     encoding='UTF8-NoBOM'
                                                     openInEditor="true"/>
                <file source='Module.psm1'
                            destination='${PLASTER_PARAM_ModuleName}.psm1'
                            openInEditor="true"/>
                <message>Your new PowerShell module project '$PLASTER_PARAM_ModuleName' has been created.</message>
    </content>
</plasterManifest>

What I learned, and some of this is just take the example and following naming convenstions, in order to get something like a company name value in the resulting psd1 you have to create a parameter value and then include it in the newModuleManifest destination section To call the parameter which in this example is ModuleCompanyName you use $PLASTER_PARAM_ModuleCompanyName.

Cut to the end, in my resulting module’s psd1 you will find:

# Company or vendor of this module
CompanyName = 'KavanaghTech'

Which is the value I entered when I started the invoke-plaster (even easier in VSCode as it is simply availabe in the command palette) using my new template and during the initial process that is the value I entered for the Company Name.

Sorry for the rambling but I just wanted to share what was a major frustration for me. I also wanted to share the greatness that is the PowerShell community.

Posted in CIM, Powershell

Better way to Reboot a computer

I saw a post of how to use the restart-computer cmdlet. They used wait to pause the process until the computer was back online. This post is just how to take it one step further. If I want my script to wait for the reboot to occur it is normally because I want to perform more actions against it. In this post I am using the restart-computer cmdlet but I am extending it to wait but I am also specifying what it will wait For.  In this case I am waiting for WinRM to come online so that I can connect to CIM.

Yes, I splatted it because I love splatting parameters for readability and flexibility.

#Requires -Version 5
<# .SYNOPSIS     Better way to reboot computers .DESCRIPTION     Really it is just an demonstration of the flexibility of restart-computer. Being able to tell the cmdlet to     wait for a specific element to be online before continuing can help with workflows that require a reboot and     then further action. .PARAMETER ServerName     Name of the computer to be restarted. .EXAMPLE     C:\PS>.\better-rebootcomputer.ps1 -servername testmachine
    Example of how to use this cmdlet
.Link
    https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.management/restart-computer
.NOTES
    ===========================================================================
    Created with: 	Visual Studio Code
    Created on:   	05.01.2017
    Created by:   	John Kavanagh
    Organization: 	TekSystems
    Filename:     	better-rebootcomputer.ps1
    ===========================================================================
    date initials: Enter first comment here
#>

[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')]
Param(
     [Parameter(Mandatory = $true,
     ValueFromPipeline = $true,
     Position = 1,
     HelpMessage = "Enter the computer name to be rebooted")]
     [ValidateScript({test-connection -Computername $_ -Count 1 -Quiet })]
     [System.String]$servername
)
$args = @{
    ComputerName = $servername
    Wait         = $True
    For          = "WinRM"
    Force        = $True
}
restart-computer @args
# Now let's test - yes I am using CIM so For has to be WinRM, WMI is up first but CIM
# requires WinRM
$sess = New-CimSession -computer $servername
Get-CimInstance -classname win32_operatingsystem -CimSession $sess<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>

 

Posted in Powershell

VSCode moving from ISE

I read a recent post where someone was claiming the ISE was still there go to because they could not run specific lines of a script. If your PowerShell extension for vscode is even close to current… select the code you want to test and press F8 just like in the ISE.

Posted in Editor, Powershell

PoSH–vscode analyzer and parameters

The more I work with Visual Studio code the more I like it, especially for PowerShell. The Integrated Terminal just gets better and better. It just makes working with scripts much easier and makes me better at crossing the t’s and dotting the i’s.

One thing I came across recently was how the ScriptAnalyzer (a tool not just for vscode ) and Visual Studio Code work together. I was working with some colleagues on taking some code for a project and assembling it into a script. Of course that meant adding advanced functionality.  I wanted to provide parameters for the input that is needed. I started adding a password parameter. While it isn’t a formal credential but rather a simple string applied to a step within the script I used the word password in the parameter name. Then I noticed green squiggly lines for the complete parameter statement. Understanding that this was just a recommendation I messed around with it a little. As soon as I changed the parameter name to something other than “password” the warning/suggestion indicator disappeared. Since I want the operator to understand what the parameter is I kept the name and will live with the green squiggly lines but I just thought that was a nice implementation.

param-detection

Posted in Powershell

Visual Studio Code – FTW

Okay it’s official, I am sold on using vscode for my PowerShell work. Little things like Ctrl+K + Ctrl+C to comment out a line…. The responsiveness that the development team is amazing. The PowerShell extension is now at 1.0 and I can’t see a reason to not move from the ISE to Visual Studio Code.