Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Walked
Apr 14, 2003

Anyone know how to query an Exchange 2007 server and check the number of messages in specific queues?

Working on automating my staff's on-call checks for them; finding iffy documentation on Exchange queries. (To be fair; half the internet is blocked at this office too)

Adbot
ADBOT LOVES YOU

Walked
Apr 14, 2003

Anyone help? :(

Getting the error:
out-lineoutput : Object of type "Microsoft.PowerShell.Commands.Internal.Format.FormatStartData" is not legal or not in
the correct sequence. This is likely caused by a user-specified "format-list" command which is conflicting with the def
ault formatting.


When running this program. However, only on the second function call. Whichever function (queues or stores) I run first; everything runs PERFECT. Once I run the second, error city.

If I remove the ft on the stores function, all is happy again, but the output is not readable.

Anyone help?

code:
Add-PSSnapin Microsoft.Exchange.Management.Powershell.Admin;

function mainMenu()
{
	Clear Host;
	Write-Host "============";
	Write-Host "= MAINMENU =";
	Write-Host "============";
	Write-Host "1. Press 1 for Exchange Queue Status";
	Write-Host "2. Press 2 for Information Store Status";
}

function queues()
{
	Get-ExchangeServer | where{$_.ServerRole -eq "HubTransport"} | Get-Queue | Sort $_.Messagecount -descending ;
}

function stores()
{
	Get-ExchangeServer | where {$_.IsMailboxServer -eq "$True" }  | Get-MailboxDatabase -status  | ft servername,storagegroup,mounted;

}



do
{
	mainMenu;
	$input = Read-Host "Enter Choice";
	
	switch($input)
	{
		"1"
		{
			queues;
			Write-Host "Press Any Key to Continue";
			$host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown");
			mainMenu;
		}
		
		"2"
		{
			stores;
			Write-Host "Press Any Key to Continue";
			$host.UI.RawUI.ReadKey("NoEcho, IncludeKeyDown");
			mainMenu;

		}
		
		default
		{
			Clear Host;
			Write-Host "Invalid option";
			$host.UI.RawUI.ReadKey("NoExcho, IncludeKeyDown");
			mainMenu;
		}
	} 
	
}until ($input -eq "q");


#Get-TransportServer | Foreach-object {Get-Queue -Server $_ | Sort-Object NextHopDomain, MessageCount, Status}


Write-Host "Press any key to exit";

$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");

Walked
Apr 14, 2003

adaz posted:

I don't have an exchange environment handy to test this on, but my experience with powershell formatting and type conversions wackiness leads me to believe something like this would work to fix it (although I'm sure someone with more knowledge would know a better way).

code:
[array]$arrStores = Get-ExchangeServer | where {$_.IsMailboxServer -eq "$True" }  | Get-MailboxDatabase -status

$arrstores |ft servername,storagegroup,mounted;
You force it convert the data to an array instead of relying on the built in type filters, that usually works for silly problems like this

Unfortunately same error; got me excited too :(

Walked
Apr 14, 2003

No good on that one adaz; but feels close. Got a few things I'm going to try; this is annoying as anything though.

Walked
Apr 14, 2003

adaz posted:

A random google search says this - what happens if you remove the ; (actually I don't even know why you included it, it's strictly speaking not necessary

I'll give that a whirl when I'm back in my exchange environment tomorrow. I'm a C# guy; the semicolon is habitual. :(

Walked
Apr 14, 2003

Walked posted:

I'll give that a whirl when I'm back in my exchange environment tomorrow. I'm a C# guy; the semicolon is habitual. :(

Stripping every single semicolon out of this didnt do poo poo. ARRRRRR I am gonna quit life. Who needs to monitor exchange anyways?

Walked
Apr 14, 2003

So piping the queues and stores functions to |Out-Default sorted it. Weird.

I still dont totally understand the pipeline. Its like learning OOP all over again. :gonk:

Walked
Apr 14, 2003

This is a simple one.

Reading the Windows Powershell Cookbook (and gently caress me this book rules).

A lot of their scipts call on others that were written.
Generally in all my readings its always "and you can use your own PS scripts as if they were cmdlets, call them like: PS> yourscripthere.ps1 - see isnt that awesome?!"

But the cookbook has you calling them sans extension. Is there a default search location for your own cmdlets or do I just need to use an alias or what?

Building up my script library at work to make life easier here. Want to streamline it best possible.

Walked
Apr 14, 2003

adaz posted:

It's called Dot Sourcing and got a bit easier in V2. The scripting guys have an article up on it a few weeks old that probably do a better job explaining it than I would:

http://blogs.technet.com/b/heyscriptingguy/archive/2010/10/07/reuse-powershell-code-to-simplify-script-creation.aspx

What I usually end up doing is tossing every function I think might be reused into like common.ps1 and all my scripts just dot source that on load. You can also just load them into your powershell profile if you mainly run the scripts as yourself, then you really don't have to worry about dot-sourcing - they are in your profile and can be run natively without any of the ps1 stuff.

Perfect. Powershell is loving killing it over here though. I am loving it; even if I'm a bit slow on picking a few things up. :)

Walked
Apr 14, 2003

WELP back again. This should be stupid loving easy but it is not. Arrgh.

Out-file and Out-default both eat the pipeline up.

Great. Except I want to output the same item to the console as to a text file (this is for health reports on the network).

Is there any way to do this other than assigning each item generated to the report a variable name and then running Out-File and Out-Default on each? Bleh

Walked
Apr 14, 2003

gently caress. Thank you.

:)

edit: Nopee; that had a complete lack of an append option. Meh.
Start-Transaction / Stop-Transaction covered my exact goals, which was just to pull all the results of a script run. It fucks up the carriage returns in Notepad; but thats minor really. It mostly looks aaaaa-ok.

No worry though :)

Walked fucked around with this message at 03:28 on Oct 19, 2010

Walked
Apr 14, 2003

Is this possible?

I've got a script that requires our domain admin account to run. So right-click, run as adminsitrator, good to go.

Then I've got it launching an outlook window and pre-populating the mail message with the results of the report.

Problem is, I cant get them to work together. If I do them together, either the administrative checks dont run (needs admin priveleges) or the outlook application wont launch (no outlook profile for the domain admin user).

Is there a way to tell it to execute a code block as the currently logged in user on a machine? I cant find much.

Walked
Apr 14, 2003

adaz posted:

Outlook is such a bitch to work with and I've run into similar problems like you're describing. The issue is the profile problems, and I'll try to not rage too much here but this is so annoying to work around. There is a way in the ComObject to specify a different username/password but I've never been able to get it to work (probably because we're running on a different domain in a different forest than our Exchange domain). You might want to check into that.

So your options are to

1.) use system.net.mail to send your email through a friendly smtp server bypassing outlook altogether

2.) Check in the outlook object for how to log on as a different user (http://msdn.microsoft.com/en-us/library/bb208225%28v=office.12%29.aspx)

3.) use the old runas.exe

code:
& 'C:\windows\system32\runas.exe' /user:mydomain\myusername "C:\Program Files\Microsoft Office\Office12\Outlook.Exe"
4.) use exchange web services which I have very little experience with other than briefly playing around for a few hours one bored day.

SMTP isnt an option; user needs a chance to review the message before it fires off.

gently caress it. Not that big a deal.
Question: Would a start-process from Powershell 2.0 work, if I kicked off a secondary script to do the outlook tasks? Such a bad work around though.

Walked
Apr 14, 2003

adaz posted:

Well, something like this should work if that's the case (haven't tested it, replace outlookprofile with name of profile you want to login to)-

code:
$cred = Get-Credential
start-process outlook -credentials $cred
$OutlookApp = New-Object -COM Outlook.Application 
$OutlookMapiNamespace = $OutlookApp.GetNamespace("mapi")
$OutlookMapiNamespace.Logon("OutlookProfile")

Probably, trying to avoid prompting for credentials as we use smart card authentication for regular user logins and I'm trying to keep it streamlined as possible.

But we'll see. Toying with it.

Walked
Apr 14, 2003

Anyone worked with WMI much?

code:
$m = Get-WmiObject Win32_OperatingSystem
$m.FreePhysicalMemory

#dostuff ................

$m.FreePhysicalMemory

Free physical memory never updates unless I create a new object:

code:
$m = Get-WmiObject Win32_OperatingSystem
$m.FreePhysicalMemory

#dostuff ................


$m = Get-WmiObject Win32_OperatingSystem
$m.FreePhysicalMemory

Any way to call an update on the $m object instead? I have this same problem working with Win32_Service - I can stop a service, do a $service.Status and itll show running until I do the new object.

Mildly frustrating to work with certain WMI objects this way; is it the only one?


edit:
Of course, this works - but gently caress me if it aint a bit clunky:
code:
(Get-WmiObject Win32_OperatingSystem).FreePhysicalMemory

Walked fucked around with this message at 21:51 on Oct 29, 2010

Walked
Apr 14, 2003

adaz posted:

well $m.psbase.Get() will refresh those values if that is what you're looking for? OTherwise you can check out the system.diagnostics namespace, might have more of what you're looking for.

$m.psbase.get() did exactly what I wanted. Thank you.

I appreciate it; though I'll poke around with system.diagnostics - the WMI Objects allow my to connect to remote hosts very easily which is really, really handy.

Walked
Apr 14, 2003

IT Guy posted:

Is the OP (April 2010) still the best source for resources?

I have zero .NET programming knowledge and my batch jobs consist of Google results. I'm interested in just full blown learning PowerShell to make my life easier and want to pick up one or two books on the subject. Where is my best start to learn PS?

Depends on your level of understanding of .NET (you said none), powershell(none), and scripting/programming in general.

Between MSDN + Oreilly's Powershell Cookbook and you've got a TON of material at your disposal, but its also not like it's a 1-2-3 "intro to this stuff" avenue.

Oreilly generally has really good stuff though, I think they have a more introductory powershell book out too.

Walked
Apr 14, 2003

What is everyone doing for version/source control?

I'm starting to grow in both number of scripts, and people I share them with to a point where I need something in place to manage it a bit better.

Looking at git or TFS Online options. Any suggestions on workflows I can move to?

Any good git primer you guys can recommend if that's the way to go?

Walked
Apr 14, 2003

Followup on the git question:

Spent part of today reading up, and fairly comfortable with the basic concepts.

However; my use case is that:

I have my local repo; makes sense
Which I'll push to VSO for changes I'm happy with.

How would I go about also getting the VSO repo synced up with a DFS namespace/fileshare at work? Basically I'd like to have a share at work that is only (and autmatically) updated with changes that are pushed to the server.

Any suggestions there? I'd like as much automation as possible so the repo and share are as in-sync as possible without human intervention.

Walked
Apr 14, 2003

Vulture Culture posted:

Create a repository on a shared drive. Create a scheduled task to automatically git pull your wanted branch(es) from VSO. Ensure it's read-only (i.e. only the user running that pull script can write to it).

That's where I'm stumbing; I cant find any documentation on how to cook in the authentication for VSO into a scheduled task. Otherwise this is 100% exactly what I'd like to do. Any tips on what to look for on that? I'm normally pretty good with google-fu, but not being a developer, not using VSO before, and not knowing git and I'm struggling :negative:

edit: Figured it out; dang.


Easy! Though documentation is not all over about this

but you can just use the VSO Personal Access token and
code:
git clone htps://{{ACCESS_TOKEN}}@project.visualstudio.com/DefaultCollection/_git/info
Thanks :)

Walked fucked around with this message at 21:52 on Sep 5, 2015

Walked
Apr 14, 2003

Judge Schnoopy posted:

I've got an odd powershell question that I can't seem to find an answer on.

When I run this locally on HostName:
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall | foreach-object {Get-ItemProperty $_.PsPath}

I get the exact results I'm looking for. When I try the same command from my computer using "Invoke-Command -computer HostName {*above command*}" it says the path does not exist.

Except I know it exists because I can run the same thing from the target computer and get my result. Is there a limitation with remote powershell that can't access this registry path? Or do I need to edit the HKCU path to specifically aim it at that computer?

My gut is that the Invoke-Command isnt picking up on the pipeline properly.
Can you try this command via invoke-command, but without the "| foreach-object.... " ?

Walked
Apr 14, 2003

beepsandboops posted:

Trying to wrap my head around when it's appropriate to use parameters and when it's not. I have a script that onboards a new user and takes input like their name, start date, etc. using Read-Host.

For stuff like that, is it better to just wrap it all into a param block? When does it make sense to use Read-Host instead?

If you ever anticipate another script calling your new employee script, then definitely paramterize.

Generally, given the choice parameters will be a bit more extensible than read-host.

Walked
Apr 14, 2003

Hey with PowerShell gallery modules- what does the x and c prefix denote? I can't find a definitive answer on Google and it's driving me mad

Walked
Apr 14, 2003

cheese-cube posted:


Not sure what you're referring to, can you provide an example?

Sorry missed this; but did manage to track down the info I was after.

xModuleName denotes "experimental"
cModuleName denotes "community provided"

I was trying to figure out what to release my module in the PS gallery as, naming-wise, and cModuleName was the way to go.

Walked
Apr 14, 2003

milk milk lemonade posted:

I'm writing a password reset script and I figured out how to get it to say "Sorry! That user doesn't exist" but I want it to return to the start of the script when that happens. Is there an easy way to do this? I've looked at a few things like erroraction but I don't think this applies when I do GetADUser and want it to either display the results or say "whoops!". If I need to start over and look at it from another angle I'd appreciate any tips on where to start!

edit: Sorry, forgot I wasn't using getADuser. This is what I'm using to return whether the account exists or not:

code:
if(dsquery user -samid $account){"Found User"}
else {"User Does Not Exist"}

There's a lot of ways to handle this (relatively easily, too); can you post your full code of psuedo code, not just the if/else block

Walked
Apr 14, 2003

So I've been cranking away as a PowerShell module I'm pretty happy with.

https://www.powershellgallery.com/packages/cDscDocker/1.1.0
https://github.com/walked/cDscDocker

This little guy will configure docker on a Server 2016 host, and join it to a docker swarm if configured as such.
If anyone else is dabbling with docker, I'd be more than welcoming of any feedback.

Requires Powershell V5 / Server 2016

I've been able to lab test this with a bunch of Server 2016 hosts; and all is well so far.

Walked
Apr 14, 2003

Mr Crucial posted:

Is there a way for a function to evaluate a passed parameter and automatically convert it to the right data type? I have a function that needs to take in a Boolean, which works fine if it's run as a one off from the command line like so:

Add-MyItem -name "Item 1" -enabled $true

Where the "enabled" parameter is defined as a Boolean within the Add-MyItem function.

But what I really want to be able to do is pipe the import from a CSV like so:

Import-CSV AllMyItems.csv | Add-MyItem

With a CSV that looks like

Name,Enabled
Item 1, $true
Item 2, $false

Problem is my script rejects the "enabled" parameter because it gets passed as type System.String regardless of whether I specific it as TRUE, true, $true, or 1 in the CSV.

code:
[Boolean]$newVariable = [System.Convert]::ToBoolean($variable)
Hopefully thats what you're looking for; grabbed out of a script I'm using that pulls boolean values out of XML


edit: If the CSV has the $ in the value, you'd need to strip those it looks like.

code:
[Boolean]$newVariable = [System.Convert]::ToBoolean(($variable).Trim('$')

Walked fucked around with this message at 16:06 on Nov 17, 2016

Walked
Apr 14, 2003

Post some source?

E:b

Walked
Apr 14, 2003

The Fool posted:

oh god sanitizing variable names

This function is called from Main. If I call it twice, I don't get errors.

code:
function Get-UserInfo($ID)
{
  Try
  {
    $ADUser = Get-ADUser -Identity $ID -Credential $cred -Server $dc -Properties $userPropertyList
  }
  Catch
  {
    $errorText = "User " + $ID + " doesn't exist in CAC AD. Creating user now."
    Write-Error $errorText
    Create-NewUser $ID
    $ADUser = Get-ADUser -Identity $ID -Credential $cred -Server $dc -Properties $userPropertyList
  }
  return $ADUser
}
This function creates the new user.

code:
function Create-NewUser($ID)
{
  $UPN = $ID + "@contoso.com"
  New-ADUser -Name $ID -AccountPassword $defaultPassword -UserPrincipalName $UPN -ChangePasswordAtLogon $true -Credential $cred -Enabled $true
}
The Main function
code:
function Main([string]$UserID)
{
    $SubUserInfo = Get-SubUserInfo $UserID | Select-Object $userPropertyList
    $MyUserInfo = Get-UserInfo $UserID | Select-Object $userPropertyList
    $MyUserInfo = Get-UserInfo $UserID | Select-Object $userPropertyList # If I run this twice on a new user, the Set-ADUser commands work the second time.

    if (!$SubUserInfo.Enabled -or !$MyUserInfo.Enabled) {
     Write-Error "User account is disabled."
     Exit 1
    }

    Set-MyADUserProperties $SubUserInfo $MyUserInfo
    $updatedUser = Get-UserInfo $UserID | Select-Object $userPropertyList
    Write-Output $updatedUser
}

Gut shot from my phone, what happens if you sleep for 10 sec before calling the problematic function?

Walked
Apr 14, 2003

FISHMANPET posted:

OK I'm tearing my hair out over here and I just have no idea how I'm supposed to move forward.

We have a powershell script. We run it to build new machines. We have an Enterprise Github subscription so the script is "stored" there. Our team (7 of us) share a single RDS server that we use as a tools server it's where all our "stuff" is. I want to keep our script in a place on that server, such that it will always be the latest version. Github is the "source of truth" so to speak and there should always be a copy of that source of truth on our tools server.

I've come up with a number of possibilities on how to solve this problem, and they all seem bad, so I'm worried that something we're doing is wrong and should be done differently.
The dumbest brute force method is to have a scheduled task that runs every <unit of time> to execute a script that does a git pull. That's totally non-elegant, and there's the (minor) issue of what happens when the script is updated in Github but the scheduled task hasn't been run yet.
I could setup a github post-commit webhook. I could then either send that webhook to an azure automation service that would then fire off a git pull on the tools server. Or I could custom write something in powershell that will listen for that webhook and do a git pull when it receives the notification. Both of those seem convoluted and require a lot of custom programming.
I could go all out and setup a CI process. I've gone slightly down the rabbit hole of looking at Visual Studio Team Services, but this is dramatically overkill, and is in no way aimed at a sys admin, but at a programmer. I could make it work, but there don't appear to be any built in "build" actions that say "copy this git repo when it changes" so I'm left writing my own script to do the git pull and having VSTS execute that when the repo changes.

None of this stuff is particularly complicated (maybe writing a powershell service to listen for a web request is...) but it's still special snowflake code that I have to write myself rather than just copy from someone else smarter than me on the internet. Which is kind of the root of my problem, this doesn't seem like an uncommon scenario yet I can't find any information about how to easily solve this problem so I'm left wondering if I'm solving the wrong problem, in which case what should I be doing differently?

I've been through this whole thought process over and over again myself.

I'm using Jenkins configured to poll SCM for changes, and to publish artifacts to a CIFS share on 'build' completion.
It helps that I've also set this up to compile all our DSC mof files and the DSC server is configured to consume those from the artifacts share.

This is a terrible blog post I wrote that covers the DSC side of what I'm doing: https://i-py.com/2017/jenkins-dsc-ci/ - but its the same basic design for all our PowerShell stuff.

Walked fucked around with this message at 01:56 on Jan 20, 2017

Walked
Apr 14, 2003

GPF posted:

Just wondering...is there some kind of function that's part of GitHub where you can pull down a hash of what's on there rather than the whole script? If there was something like that, it'd be easy enough to grab the Github hash, then hash your local copy and do a comparison using that launcher script idea. Hash doesn't match, pull the remote "more truthy" script. Hash matches, run the local copy.

Looks like the git api just dumps the whole file back anyways, but here you go

code:
$a = iwr "https://api.github.com/repos/walked/cDscDocker/contents/cDscDocker.psm1"
($a.Content | ConvertFrom-Json).sha
(but the http response to the webrequest contains the whole file in base64 encoding anyways so :toot: )

Walked
Apr 14, 2003

CLAM DOWN posted:

I have a single command within a script that takes forever to process (no way around this) and I wish MS would add a way for me to display a progress bar for this single command :( Write-Progress is annoying and limited.

Just do it the microsoft way; have it load at a linear rate until it's at ~90% and then just let it sit there without explanation until the task completes or fails.

:negative:

Walked
Apr 14, 2003

Avenging_Mikon posted:

Holy gently caress I love powershell. Turns out my supervisor had made a script to grab users from an AD group and output it to a csv file. It took a couple tries to configure the script to what I needed, but the errors were useful and helped me tune it, and now I'm in a terminal server playing around with Powershell ISE to see how it behaves (Only 32-bit Win 7 on the actual desktop, server 2016 on the terminal server), and I'm in god-damned love. I'm debating setting up a vpn to my home computer with Win 10 so I can gently caress around while learning at work without nuking a server accidentally.

AWS Free Tier dude.

Easy way to run a cloud VM for loving around with, without risking anyone's infrastructure.

Adbot
ADBOT LOVES YOU

Walked
Apr 14, 2003

Inspector_666 posted:

Welp, guess it's time to learn a thing.

Well worth learning.

Sapien PowerShell Studio actually has pretty good boilerplate code / module projects for learning what those look like. I think its a 30 or 60 day trial, too. Makes getting started with Modules really easy

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply