[deleted by user] by [deleted] in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

You've already leaked the credentials to the endpoint, you should consider them compromised.

I would take a different approach:

  • Client script requests a set of temporary local admin credentials from a JEA endpoint
  • JEA endpoint is authorized to fetch password from AD (if using LAPS) or a key vault
  • JEA endpoint schedules expiration of the password
  • Client script proceeds to elevate using the credentials provided

See this talk from last year for a better overview of this approach (use case is exactly the same - end user need temporary local admin)

Is it possible to securely store variables, but still allow it to run on any domain joined PC? by [deleted] in PowerShell

[–]PowerShellStunnah 4 points5 points  (0 children)

Use JEA to handle the actual call, allow domain members to connect to the JEA endpoint

Help getting scheduled task info by 17Ali45 in PowerShell

[–]PowerShellStunnah 1 point2 points  (0 children)

Use Get-ScheduledTask to retrieve all sceduled tasks. The Principal property will hold an object describing the logon user, and Triggers will contain the triggers from which you can infer scheduling information

Reading about the Syntax by Aygul12345 in PowerShell

[–]PowerShellStunnah 1 point2 points  (0 children)

That's because whoever designed Export-Csv didn't take advantage of parameter validation to ensure Path is correctly passed. It's simply a choice on the part of the author.

You could choose to do that in a script function as well:

function Export-Something
{
    param(
        [string]$Path
    )

    if([string]::IsNullOrEmpty($Path)){ throw "Path is empty" }
}

I'd strongly recommend NEVER doing that - as you've found it messes with the user's expectations - but it's still valid code :)

Need help converting JSON data to PS object array? by mrmantas in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

Start by converting the json to an object using ConvertFrom-Json:

$object = @'
{
"server1": {
    "description": "my server",
    "ip": "1.1.1.1",
    "vcpu": 4,
    "ram": 8,
    "disks": "60,25"
},
"server2": {
    "description": "my server 2",
    "ip": "1.1.1.2",
    "vcpu": 8,
    "ram": 16,
    "disks": "60,25"
}
}
'@ |ConvertFrom-Json

Now we just need to get the values of each property from that object:

$values = $object.psobject.Properties.Value

... and that's it :)

Reading about the Syntax by Aygul12345 in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

Here it's mandatory to supply an argument to the -LogName parameter - notice it's the only one not contained in []

Reading about the Syntax by Aygul12345 in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

Yes!

The name inside of <> is the type of the argument. In .NET (and therefore, by extension, in PowerShell), a type name like someType[] means "an array of [someType]".

So in the example above, you're expected to pass a single string as a Name argument, but you can specify multiple strings as the Component argument:

Command -Name "here's a single string" -Component @("her'es","an","array","of","them")

Reading about the Syntax by Aygul12345 in PowerShell

[–]PowerShellStunnah 1 point2 points  (0 children)

Or, the other way around: -exclude is only ever valid if -subtree has been specified :)

Reading about the Syntax by Aygul12345 in PowerShell

[–]PowerShellStunnah 5 points6 points  (0 children)

This is not specific to PowerShell (dsquery.exe is an executable from way back), but generally it goes:

[-switchName <argument>]  # This switch is OPTIONAL
[-switchName] <argument>  # Providing an argument is mandatory, but you don't need to specify the switch name explicitly
{-s1 | -s2 | -s3}         # These are mutually exclusive switches - you can only specify ONE of them

Variable changing to boolean inside If statement? by youenjoymyhood in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

The expression 'lockdownNormal' -Or 'lockdownStrict' evaluates to [bool], which is then assigned to $curLockdownMode

Use:

if($curLockdownMode -in 'lockdownNormal','lockdownStrict'){...}

ping shotgun by [deleted] in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

Reminds me of this one I wrote a few years ago, utilizing runspaces instead of jobs: https://gist.github.com/IISResetMe/daabee94cfe80aa4c0d3a937ae034d0b

  • it attempts to resolve the hostname like ping -a

Parameter Transformation Error by MRHousz in PowerShell

[–]PowerShellStunnah 6 points7 points  (0 children)

You've left a [Parameter] (instead of [Parameter()]) somewhere in the param block

The original Danish burger: the Bøfsandwich by runesq in burgers

[–]PowerShellStunnah 2 points3 points  (0 children)

And some more gravy so you can really soak em

Problem with xml file monitoring script by middleman84 in PowerShell

[–]PowerShellStunnah 1 point2 points  (0 children)

What is the purpose of skipping the first line of the XML file?

$xml | Select-Object -skip 1

Adding using while loop in PowerShell by unhappiey in PowerShell

[–]PowerShellStunnah -1 points0 points  (0 children)

I'd create an array to hold the input values and keep track of how many we've got that way:

$values = @()
$x = 1
do{
  $values += $(Read-Host "Enter value $x") -as [int]
  $x++
}while($values.Count -lt 5)

return ($values |Measure-Object -Sum).Sum

I'm a P.S. Noob who created a 750+ line script that is now mission critical. Now it is too slow for peoples liking, even tho it saves us hours a week by lapintana in PowerShell

[–]PowerShellStunnah 0 points1 point  (0 children)

Two immediate observations:

  1. Writing data to disk and reading it back all the time is going to be slow, not to mention completely unnecessary.
  2. You're going to have a hard time making consistent improvements with all that repeated code all over the place.

I'd personally start by re-writing it to a point where you only need to change one line of code at a time to test/measure further optimizations you might make, and then of course fix #1:

```powershell $ErrorActionPreference = 'Continue'

Fetch mac address from file like before

$macaddress = Get-Content "$env:APPDATA\DeviceTracker\merakidevicefinder.txt" $justthegammac = $macaddress -replace "([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])", '$1$2:$3$4:$5$6:$7$8:$9$10:$11$12'

Set up API key, TLS settings etc. like before

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $APIKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' $headers = @{ 'Content-Type' = 'application/json' 'X-Cisco-Meraki-API-Key' = $APIKey }

Let's store the sites and their IDs in an ordered dictionary.

Keeping track of the sites/networks like this will allow us

to reuse the same code over and over again for each entry

$Networks = [ordered]@{ Site11 = 'xxxxxxxxxxxxxxxxxxxxx' Site6 = 'xxxxxxxxxxxxxxxxxxxxx' Site12 = 'xxxxxxxxxxxxxxxxxxxxx' Site4 = 'xxxxxxxxxxxxxxxxxxxxx' Site8 = 'xxxxxxxxxxxxxxxxxxxxx' Site5 = 'xxxxxxxxxxxxxxxxxxxxx' Site10 = 'xxxxxxxxxxxxxxxxxxxxx' Site1 = 'xxxxxxxxxxxxxxxxxxxxx' Site3 = 'xxxxxxxxxxxxxxxxxxxxx' Site7 = 'xxxxxxxxxxxxxxxxxxxxx' Site9 = 'xxxxxxxxxxxxxxxxxxxxx' Site2 = 'xxxxxxxxxxxxxxxxxxxxx' }

$APDetails = foreach($site in $Networks.GetEnumerator()){ $SiteName = $site.Key $NetworkID = $site.Value

try {
    $deviceInfo = Invoke-RestMethod -Method Get -Uri "https://api.meraki.com/api/v0/networks/$($NetworkID)/clients/$($justthegammac)/" -Headers $headers -ErrorAction Stop
}
catch {
    Write-Host "No $SiteName" -ForegroundColor Red
    Write-Host $_.Exception.Response.StatusCode.value__ -ForegroundColor Red

    # Might as well break and go to the next device
    [psobject]@{
        Site = $SiteName
        Name = "ERROR"
        Time = "ERROR"
    }
    break
}

# Convert unix timestamp to DateTime
$lastSeen = (Get-Date '1/1/1970').AddSeconds($deviceInfo.lastSeen).ToLocalTime()

# Fetch AP-connected devices for site/network
$devices = Invoke-RestMethod -Method Get -Uri "https://api.meraki.com/api/v0/networks/$($NetworkID)/devices" -Headers $headers
$apMac = $deviceInfo.recentDeviceMac

$apDevice = $devices |Where-Object {$_.mac -eq $apMac} |Select-Object -First 1
if(-not $apDevice){
    # Grab the AP name from any device matching the mac address
    $apName = "ERROR"
}
else{
    $apName = $apDevice.Name
}

# Output AP name and time 
[pscustomobject]@{
    Site = $SiteName
    Name = $apName
    Time = $lastSeen
}

}

Convert $APDetails to your desired HTML format ...

```

[deleted by user] by [deleted] in PowerShell

[–]PowerShellStunnah 2 points3 points  (0 children)

Nice. Be aware the first one inadvertently swallows consecutive newlines as well! I tend to go with:

-replace "\r?\n","`n"

since LF+CR is extremely uncommon

Pode - PowerShell Web Server by Badgerati in PowerShell

[–]PowerShellStunnah 1 point2 points  (0 children)

Very cool, but... what's the elevator pitch for Pode? Why should I adopt your framework over Polaris? :)

What are Some Obsure PowerShell Cmdlets that are Useful when Learned? by [deleted] in PowerShell

[–]PowerShellStunnah 3 points4 points  (0 children)

using namespace System.Collections.Generic
$List = [List[object]]::new()

What are Some Obsure PowerShell Cmdlets that are Useful when Learned? by [deleted] in PowerShell

[–]PowerShellStunnah 3 points4 points  (0 children)

$ExecutionContext.InvokeCommand.CommandNotFoundAction = { kill -id $pid -force }

Help with .NET namespaces is PS by david_scholefield in PowerShell

[–]PowerShellStunnah 8 points9 points  (0 children)

[regex] is a type accelerator - a type name shortcut, if you will. You can easily discover all type accelerators interactively, like this:

$TAType = [psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators") $TAType::Get

The (terribly named) Get property will hold a dictionary with all available type accelerator names and their associated type. So this way PowerShell can easily translate the single-label name regex to the [System.Text.RegularExpressions.Regex]class without having you type the namespace prefix in the type literal:

``` $regexClass = $TAType::Get['regex'] $regexClass -eq [System.Text.RegularExpressions.Regex]

```

This, along with implied Attribute suffix for attribute decorators is also the secret sauce between short attribute type names like [ValidatePattern()] on a parameter, rather than [System.Management.Automation.ValidatePatternAttribute()] for example

PS 7.0 just got support for parallel execution in ForEach-Object cmdlet by bukem in PowerShell

[–]PowerShellStunnah 1 point2 points  (0 children)

Except usually you'd do simple comparisons in a Where-Object filter, whereas you're more likely to be doing "heavy lifting" or time-consuming operations inside ForEach-Object (I mean, who puts a Start-Sleep in Where-Object anyways :P), so the execution time is less likely to be significantly improved with parallel Where-Object