TFS-Powershell Scripting - powershell

I have this script which runs fine with no issue on the server locally but when I made a task in Team Foundation Server(update2017) and run it from there it throws an error, the error is after the script for reference.
param(
[string]$ServiceNames
)
if([string]::IsNullOrWhiteSpace($ServiceNames))
{
throw "Missing argument [-ServiceNames $ServiceNames]"
}
$Services=$ServiceNames.Split(",")
foreach($Service in $Services)
{
if(Get-Service $Service | Where {$_.status –eq 'Stopped'})
{
Get-Service $Service | Where {$_.status –eq 'Stopped'} | Start-Service
Write-Host "$Service has been started."
}
else
{
Write-Host "$Service is already running."
}
}
and this error came.
if(Get-Service $Service | Where {$_.status â?"eq 'Stopped'})
Unexpected token 'â?"eq 'Stopped'})
Thanks in advance.

Yes, copy/Paste from Word or Outlook always inserts characters you don't want in the editor. For that i have put below function in my Powershell profile file.
This is not meant as a direct answer to this question because TheIncorrigible1 already gave that.
It may however help others.
function Editor-ReplaceSmartQuotes {
## this function replaces "smart-qoutes" and long dashes you get
## when pasting from Word into normal straight characters (" ' -)
$text = Editor-GetSelectedText
$psISE.CurrentFile.Editor.InsertText(($text -creplace '[\u201C\u201D\u201E\u201F\u2033\u2036]', '"' `
-creplace "[\u2018\u2019\u201A\u201B\u2032\u2035]", "'" `
-creplace "[\u2013\u2014\u2015]", "-"))
}
and added it to my ISE menu with:
Editor-AddMenu "Replace Smart_Quotes in Selection" {Editor-ReplaceSmartQuotes} "Alt+Q"

Related

Powershell script to Stop and start windows Service using S.no

I have a listed my Windows Service Names in the Text file and I have added the code to display it by adding the S.no preceding to the Names,
Listofservices.txt contains
Print Spooler
Windows Update
Remote Desktop Services
Get-Content 'C:\Services\Listofservices.txt' | ForEach-Object { $i = 1 } { "$i.$_" ; $i++ }
Result
Print Spooler
Windows Update
Remote Desktop Services
now I would like to stop, start the services by entering only the S.no and I don't want to type the exact full name
$userinput = read-host -prompt "Enter the S.no to Stop/Start"
Stop-Service -Name "$userinput" -Force -Confirm
say for example if i enter the number 1 the Print Spooler service will be stopped
Here is one way you could do it following the code you already have, but as stated in comments, this is much simpler to do with Out-GridView -PassThru. Also do note, for these services, the PowerShell process will most likely require to be elevated.
$file = Get-Content path\to\file.txt
$file | ForEach-Object { $i = 1 } { "$i.$_" ; $i++ }
$userinput = Read-Host "Enter the S.no to Stop/Start"
try {
$choice = $file[-1 + $userinput]
if(-not $choice) {
throw 'Invalid selection..'
}
$service = Get-Service $choice
if('Running' -eq $service.Status) {
$service.Stop()
"$($service.Name) has been stopped.."
return # end the script here
}
$service.Start()
"$($service.Name) has been started.."
}
catch {
if($_.Exception.InnerException.InnerException.NativeErrorCode -eq 5) {
return "Process needs to be elevated."
}
"An error ocurred: $_"
}

Exit from while loop but keep shell open: powershell

For learnig Powershell I've wrote a script that choose a film randomly from a list, until the list runs out, but, at the end of list I want that the shell keeps open... I've tried many options Break/Return/exit... nothing to do... tried to add the last if condition in to the while condition but, not works, at the end of list an error message says that the array is empty/null, or shell quits after last film...
Yes, I can put a pause instead of return, for that script would be ok, but it doesn't seems an "elegant" solution...
The icing on the cake would be a better option to trim the extension from film name..! Because in my mode, a film name that finish with a "m", "k", or "v", these chars are trimmed out toghether with the ".mkv" expression! :)
Can someone drive me please?
This is the code:
$LastFile = (Get-Item "F:\DATA\Films list\*" | Where-Object {$_.Name -match "Title"} | sort LastWriteTime | select -last 1).FullName
$TitleList = Get-Content $LastFile | where { $_ -notmatch "4K" }
$TitleList.Count
$Listed = New-Object System.Collections.ArrayList
Foreach ( $film in $TitleList ) {
$Listed.Add("$film") | out-null
}
$RandomFilm = Get-Random -InputObject $Listed
Write-Host $RandomFilm.Trim('.mkv') -ForegroundColor Green
$Listed.Remove("$RandomFilm")
$TitleCount = 1
echo "_________________________________________________________________________________________"
echo "`n`n"
$Answer = Read-Host "RETURN for new film, q for quitting..."
while ( "q" -notcontains $Answer) {
echo "`n`n"
$RandomFilm = Get-Random -InputObject $Listed
if ( $RandomFilm -ne $null ) {
Write-Host $RandomFilm.Trim('.mkv') -ForegroundColor Green
$Listed.Remove("$RandomFilm")
$TitleCount++
$TitleCount
if ( $TitleCount -gt $TitleList.Count ) {
Write-Host "END OF LIST..." -ForegroundColor red
Return
}
else {
echo "_________________________________________________________________________________________"
echo "`n`n"
$Answer = Read-Host "RETURN for new film, q for quitting..."
}
}
}
Several ways of doing this. If you are running your script with powershell then $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")at the end of the script is a good option (this will not work with powershell_ise tho). In ISE you can add a read-host at the end.
If you are running your script from a shortcut you can add -NoExit: powershell.exe -NoExit -file .\script.ps1
The icing on the cake would be a better option to trim the extension from film name..! Because in my mode, a film name that finish with a "m", "k", or "v", these chars are trimmed out toghether with the ".mkv" expression! :)
Im not quite sure I understood this part, could you please elaborate.

Foreach loop not running through list of entries

I've tried searching this multiple times but havent resolved the issue. I have a list of servers in $mediaagentlist, the foreach loop is supposed to run through each one and get the state of certain services:
$mediaagentlist = "cs0400ma01
cs0400ma02"
[string]$Commcell_Input = $args[0]
$MAChoice = $args[1]
if ($MAChoice -eq $null)
{
Write-Output "No media agent was specified, running against all MAs in the Commcell..."
#Run this loop for each MA which is stored in Mediaagentlist
foreach ($Mediaagent in $Mediaagentlist)
{
Write-Output $Mediaagent
$GxCLMgrS_State = Invoke-Command -ComputerName $Mediaagent {Get-Service -name "GxClMgrS(Instance001)"}
$GXMMM_State = Invoke-Command -ComputerName $Mediaagent {Get-Service -name "GXMMM(Instance001)"}
$GxCVD_State = Invoke-Command -ComputerName $Mediaagent {Get-Service -name "GxCVD(Instance001)"}
Write-Output "Client manager service state: " $GxCLMgrS_State.Status
Write-Output "Media manager mount service state: " $GXMMM_State.Status
Write-Output "Communications service state: " $GxCVD_State.Status
}
}
How do I correct this so the for each loop runs through the list of entries in $mediaagentlist and runs the code for each server?
Thanks in advance!
It looks like your issue is here
$mediaagentlist = "cs0400ma01
cs0400ma02"
It looks like your missing a closing qoute per word and a comma
try
$mediaagentlist = "cs0400ma01", "cs0400ma02"
or
$mediaagentlist = #("cs0400ma01", "cs0400ma02")
Or you can define a multi-line string, then split on new lines, if there's a reason you needed the input to be a single multi-line string:
$mediaagentlist = "cs0400ma01
cs0400ma02" -split '[\r\n]+'

How to configure a timeout for Read-Host in PowerShell

Like I said, this code works in PowerShell version 2, but not in PowerShell version 5.
function wait
{
$compte = 0
Write-Host "To continue installation and ignore configuration warnings type [y], type any key to abort"
While(-not $Host.UI.RawUI.KeyAvailable -and ($compte -le 20))
{
$compte++
Start-Sleep -s 1
}
if ($compte -ge 20)
{
Write-Host "Installation aborted..."
break
}
else
{
$key = $host.ui.rawui.readkey("NoEcho,IncludeKeyup")
}
if ($key.character -eq "y")
{Write-Host "Ignoring configuration warnings..."}
else
{Write-Host "Installation aborted..."
}}
The official documentation or Read-Host -? will tell that it's not possible to use Read-Host in that manner. There is no possible parameter to tell it to run with some kind of timeout.
But there are various other questions detailing how to do this in PowerShell (usually utilizing C#).
The idea seems to be to check whenever the user pressed a key using $Host.UI.RawUI.KeyAvailable and check that for the duration of your timeout.
A simple working example could be the following:
$secondsRunning = 0;
Write-Output "Press any key to abort the following wait time."
while( (-not $Host.UI.RawUI.KeyAvailable) -and ($secondsRunning -lt 5) ){
Write-Host ("Waiting for: " + (5-$secondsRunning))
Start-Sleep -Seconds 1
$secondsRunning++
}
You could use $host.UI.RawUI.ReadKey to get the key that was pressed. This solution probably would not be acceptable if you need more complex input than a simple button press. See also:
Windows PowerShell Tip of the Week - Pausing a Script Until the User Presses a Key
PowerTip: Use PowerShell to Wait for a Key Press (Hey, Scripting Guy!)
Seth, thank you for your solution. I expanded on the example you provided and wanted to give that back to the community.
The use case is a bit different here - I have a loop checking if an array of VMs can be migrated and if there are any failures to that check the operator can either remediate those until the checks clear or they can opt to "GO" and have those failing VMs excluded from the operation. If something other than GO is typed state remains within the loop.
One downside to this is if the operator inadvertently presses a key the script will be blocked by Read-Host and may not be immediately noticed. If that's a problem for anyone I'm sure they can hack around that ;-)
Write-Host "Verifying all VMs have RelocateVM_Task enabled..."
Do {
$vms_pivoting = $ph_vms | Where-Object{'RelocateVM_Task' -in $_.ExtensionData.DisabledMethod}
if ($vms_pivoting){
Write-Host -ForegroundColor:Red ("Some VMs in phase have method RelocateVM_Task disabled.")
$vms_pivoting | Select-Object Name, PowerState | Format-Table -AutoSize
Write-Host -ForegroundColor:Yellow "Waiting until this is resolved -or- type GO to continue without these VMs:" -NoNewline
$secs = 0
While ((-not $Host.UI.RawUI.KeyAvailable) -and ($secs -lt 15)){
Start-Sleep -Seconds 1
$secs++
}
if ($Host.UI.RawUI.KeyAvailable){
$input = Read-Host
Write-Host ""
if ($input -eq 'GO'){
Write-Host -ForegroundColor:Yellow "NOTICE: User prompted to continue migration without the blocked VM(s)"
Write-Host -ForegroundColor:Yellow "Removing the following VMs from the migration list"
$ph_vms = $ph_vms | ?{$_ -notin $vms_pivoting} | Sort-Object -Property Name
}
}
} else {
Write-Host -ForegroundColor:Green "Verified all VMs have RelocateVM_Task method enabled."
}
} Until(($vms_pivoting).Count -eq 0)
Also note that all this $Host.UI stuff doesn't work from the Powershell ISE.
To find out from within a script you could test for $Host.Name -eq "ConsoleHost". When true you can use the code from this topic. Otherwise you could use $Host.UI.PromptForChoice or any other way of showing a dialog box. With System.Windows.Forms.Timer you can then set a timer, and code to close the dialog box or form can be run when it expires.

powershell Import-csv pop up

so i am working with a bit of code that after setting a static location for the CSV i am using for import. When i run the code it seems to run until i get the Windows can't open this File pop. you know the one with what do you want to do options, like user the web services to find the correct program. i am copying the code so hopefully someone can point on where i made this fubar. just for note before i made the CSV static the Script asked you to type the location in every time so maybe i missed a setting there
if ($args[0] -eq $null)
{
$userNameFile = D:\lync_creation\userlog.csv
$userNameFile = $usernamefile -replace '"',""}
else
{$usernamefile = $args[0]}
if ($userNameFile -ne "")
{$csv=import-csv $userNameFile}
else
{"Could not find a valid .csv with the user information."
exit}
foreach($c in $csv)
# enable for lync
{
"Enabling " + $c.Identity + " for Lync 2010"
Enable-csuser -identity $c.Identity -registrarpool pool01.west.com –sipaddresstype EmailAddress
}
write-host "Press any key to continue..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,AllowCtrlC")
You are seriously over complicating things if you're just going to use a static location for your CSV file.
$csv = Import-CSV D:\lync_creation\userlog.csv
foreach($c in $csv){
"Enabling $($c.Identity) for Lync 2010"
Enable-csuser -identity $c.Identity -registrarpool pool01.west.com –sipaddresstype EmailAddress
}
write-host "Press any key to continue..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,AllowCtrlC")
The first line imports the CSV file into a variable.
The next 4 loops through all entries in that variable, write the host who it's enabling and then enables the person.
The last 2 lines give a Press any key to continue message and then waits for a key press before continuing.