I have a build that creates .zip package and projectName.SetParameters.xml i want to overide the parameters in The projectName.SetParameters.xml file with my script
I have a powershell script with Mandotary parameters, I want the user to input their username and password before they can deploy to IIS in TFS i was following this guide link
UPDATE: The REalese build works but it doesn't ask the user to input the username and password, Do i have to set them manually inside the argument box on the Powershell step?
In my TFS I Have a powershell step i added the argument -paramsFilePath C:/somepath/.../.../projectName.SetParameters.xml
param(
[string]$paramsFilePath,
[Parameter(Mandatory=$true)]
[string]$username,
[Parameter(Mandatory=$true)]
$password
)
Write-Verbose -Verbose "Entering script setParameters.ps1"
Write-Verbose -Verbose ("Path to Parameters: {0}" -f $paramsFilePath)
# get the environment variables
$vars = Get-ChildItem -path env:*
# read in the setParameters file
$contents = Get-Content -Path $paramsFilePath
# perform a regex replacement
$newContents = "";
$contents | % {
$line = $_
if ($_ -match "__Username__") {
$setting = Get-ChildItem -path env:* | ? { $_.Name -eq $Matches[1] }
if ($setting) {
Write-Verbose -Verbose ("Replacing key {0} with value from environment" -f $username.Name)
$line = $_ -replace "__Username__", $username.Value
}
}
$newContents = $line
}
Write-Verbose -Verbose "Overwriting SetParameters file with new values"
Set-Content $paramsFilePath -Value $newContents
Write-Verbose -Verbose "Exiting script setParameters.ps1"
Here is my Parameters.xml code
<!--?xml version="1.0" encoding="utf-8" ?-->
<parameters>
<parameter name="machineURL" description="Please enter the name of the Environment" defaultvalue="_UrlValue_" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='machineURL']/#value">
</parameterentry>
</parameter>
<parameter name="username" description="Please enter the username" defaultvalue="__UserName__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='username']/#value">
</parameterentry>
</parameter>
<parameter name="password" description="Please enter the password" defaultvalue="__Password__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='password']/#value">
</parameterentry>
</parameter>
</parameters>
The PowerShell execution in TFS Build and Release is only in non-interactive mode possible. The build and release process will only streams the execution result to the build console.
You have to create a variable with the username. For the password you should use hidden variable:
Yes you have to place the arguments inside the argument box of the
PowerShell step
Note: The password field seems secure and not readable but it is not really hard to read the content of a hidden variable.
Create the variables and set the values. After that you can use this command line parameter in the PowerShell step argument box.
-paramsFilePath $(paramsFilePath) -username $(username) -password $(password)
Related
This question already has answers here:
How to pass a variable to new console window in Powershell
(2 answers)
Closed last year.
I have a script that opens a powershell console as admin and do sth in eventlog.
I have two variables that i the new admin-PS console needs.
[string] $PiEventLog = "'Company Name Prv.Limt'"
[String] $PiEventLogSource = "'XY-Test'"
I am opening the new PS-Console like this
start powershell -Verb runas {
If(Get-EventLog -List | ?{$_.Log -like $PiEventLog}){
Write-Host "EventLog already exists." -ForegroundColor Yellow
}
else{
New-EventLog -LogName $PiEventLog -Source $PiEventLogSource -ErrorAction Stop
Write-Host "EventLog was successfully created." -ForegroundColor Green
}
Read-Host "Press any key to close the console..."
}
If i try to execute the script, i get the following error:
The argument for the parameter "LogName" cannot be checked. The
argument is NULL or empty. Specify an argument that is not NULL or
empty and re-execute the command.
anyone got an idea, how i can give those two variables to the new PS-console, without having to set two different variables in the new console?
I believe this should work, it's easier if you use a Here-String. Since you're using the -like operator, I would assume you're looking for a Log that "contains" the input given in $PiEventLog, in that case, you should use wildcard characters: -like "*$PiEventLog*".
param(
[string] $PiEventLog = 'Company Name Prv.Limt',
[String] $PiEventLogSource = 'XY-Test'
)
$command = #"
If(Get-EventLog -List | Where-Object Log -Like '*$PiEventLog*'){
Write-Host 'EventLog already exists.' -ForegroundColor Yellow
}
else{
New-EventLog -LogName $PiEventLog -Source $PiEventLogSource -ErrorAction Stop
Write-Host 'EventLog was successfully created.' -ForegroundColor Green
}
Read-Host "Press any key to close the console..."
"#
Start-Process powershell -Verb RunAs -ArgumentList '-c', $command
Then you call this script like:
PS /> ./script.ps1 -PiEventLog 'something' -PiEventLogSource 'something'
I create a zip Package in my build then i deploy it to a diffrent machine i am pasing few Parameters in my parameters.xml
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<parameter name="WebSiteUserName" description="Please enter the username" defaultvalue="__WebSiteUserName__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/connectionStrings/add[#key='WebSiteUserName']/#value">
</parameterentry>
</parameter>
<parameter name="WebSiteUserPassword" description="Please enter the password" defaultvalue="__UserPassword__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/connectionStrings/add[#key='WebSiteUserPassword']/#value">
</parameterentry>
</parameter>
<parameter name="WebSiteDomain" description="Domiain" defaultvalue="__Domain__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[#key='WebSiteDomain']/#value">
</parameterentry>
</parameter>
</parameters>
</parameters>
Then i run a powershell script
param(
[string]$paramsFilePath
)
Write-Verbose -Verbose "Entering script Replace-SetParameters.ps1"
Write-Verbose -Verbose ("Path to SetParametersFile: {0}" -f $paramsFilePath)
# get the environment variables
$vars = Get-ChildItem -path env:*
# read in the setParameters file
$contents = Get-Content -Path $paramsFilePath
# perform a regex replacement
$newContents = "";
$contents | % {
$line = $_
if ($_ -match "__(\w+[\.\w+]*)__") {
$setting = Get-ChildItem -path env:* | ? { $_.Name -eq $Matches[1] }
while ($setting) {
Write-Verbose -Verbose ("Replacing key {0} with value from environment" -f $setting.Name)
$line = $_ -replace "__(\w+[\.\w+]*)__", $setting.Value
}
}
$newContents += $line + [Environment]::NewLine
}
Write-Verbose -Verbose "Overwriting SetParameters file with new values"
Set-Content $paramsFilePath -Value $newContents
Write-Verbose " Assigning Parameters"
Write-Verbose -Verbose "Exiting script Replace-SetParameters.ps1"
It will go through the parameters file and replace the parameters token with the enviromental variable.
In my setParamaters.xml file The WebSiteUsername only gets changed
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<setParameter name="IIS Web Application Name" value="Default Web Site/SomeWebsite" />
<setParameter name="WebSiteUserName" value="username" />
<setParameter name="WebSiteUserPassword" value="__UserPassword__" />
<setParameter name="Web.config Connection String" value="SomeValueForConnection" />
</parameters>
I dont know why this is happening. Any Thoughts?
I think you want to get the password from a TFS release definition environment.
You can´t access hidden fields with
$vars = Get-ChildItem -path env:secretVariable
There is a way but that´s only works in the context of a TFS VNext build or release extension.
In your case the only possibility of access is to set the variable as a script argument like this:
-paramsFilePath $(paramsFilePath) -password $(secretVariable)
In your script add the parameter like
param(
[string]$paramsFilePath,
[string]$password
)
Recently we did a move and a rename of an AppFabric configuration database.
The rename was from default name "AppFabricConfigurationDatabase" to "AppFabricPreOrdersConfiguration"
DistirbutedCacheService.exe.config was changed with the new database and server name
<clusterConfig provider="System.Data.SqlClient" connectionString="Data Source=NEWSERVER;Initial Catalog=AppFabricPreOrdersConfiguration;Integrated Security=True" />
and the service starts succesfully.
But from this point on the "caching administration powershell" does not start anymore because when use-cachecluster is called it still tries to connect to the old server / database.
Test connection failed for ConnectionString Data Source=OLDSERVER;Initial Catalog
=AppFabricCacheConfigurationDatabase;
Use-CacheCluster : ErrorCode:SubStatus:Invalid provider and c
onnection string read.
Where does powershell read those values from? Apparently not from the config file of the service but where then?
Since I can't stop the cluster I've tried to see if the connection string would be changed without restarting and basically just calling Remove-CacheAdmin and Add-CacheAdmin....it worked!
Of course the script would have to be run on each host so not good for large setups but a restart is not really needed apparently
param ([string] $provider, [string] $newConnectionString)
function Main {
if ( (! $provider) -or (! $newConnectionString))
{
Write-Host "Usage: ChangeConnString.ps1 <provider> <newConnectionString>"
exit(1)
}
Import-Module "DistributedCacheAdministration"
Import-Module "DistributedCacheConfiguration"
[Reflection.Assembly]::LoadWithPartialName('Microsoft.ApplicationServer.Caching.Management') | Out-Null
[Reflection.Assembly]::LoadWithPartialName('System.Management.Automation') | Out-Null
[Reflection.Assembly]::LoadWithPartialName('System.Management.Automation.Runspaces') | Out-Null
Remove-CacheAdmin
Add-CacheAdmin -Provider $provider -ConnectionString $newConnectionString
}
The scripts provided by the other users did not work for me. I encountered exceptions. I was able to work around this issue by editing the registry on each host and restarting the service.
The connection string is stored here: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AppFabric\V1.0\Configuration
The value is named "ConnectionString"
Under the user hive, there's another instance of the connection string. I don't know if you need to change this or not, but I did. HKEY_CURRENT_USER\Software\Microsoft\AppFabric\V1.0\Temp
That worked for me. Don't forget you also need to edit the ClusterConfig ConnectionString in DistributedCacheService.exe.config under C:\Program Files\AppFabric 1.1 for Windows Server
You need to call Remove-CacheAdmin and then Add-CacheAdmin to change the cache admin connection on each admin host
This Microsoft Powershell script - (.EXE download, script reproduced below) - changes the connection string on all hosts in a cluster.
param ([string] $provider, [string] $newConnectionString)
function Main {
if ( (! $provider) -or (! $newConnectionString))
{
Write-Host "Usage: ChangeConnString.ps1 <provider> <newConnectionString>"
exit(1)
}
Import-Module "DistributedCacheAdministration"
Import-Module "DistributedCacheConfiguration"
Use-CacheCluster
Write-Host "Stop the cache cluster if it is running"
$clusterRunnig=$true
&{
Stop-CacheCluster -EA Stop
}
trap [DataCacheException] {
#'Error Category {0}, Error Type {1}, ID: {2}, Message: {3} {4}' -f $_.CategoryInfo.Category, $_.Exception.GetType().FullName, $_.FullyQualifiedErrorID, $_.Exception.Message, $_.Exception.ErrorCode;
#12008: ErrorCode<ERRCAdmin008>:SubStatus<ES0001>:No hosts running in cluster
if ($_.Exception.ErrorCode -eq 12008)
{
write-host "Cluster is not running"
$clusterRunnig=$false
continue
}
}
[Reflection.Assembly]::LoadWithPartialName('Microsoft.ApplicationServer.Caching.Management') | Out-Null
[Reflection.Assembly]::LoadWithPartialName('System.Management.Automation') | Out-Null
[Reflection.Assembly]::LoadWithPartialName('System.Management.Automation.Runspaces') | Out-Null
SetCacheConnectionString $provider $newConnectionString
Write-Host "Connection string is altered on all the cache hosts. Now changing the connection string for cache admin"
Remove-CacheAdmin
Add-CacheAdmin -Provider $provider -ConnectionString $newConnectionString
if ($clusterRunnig -eq $true)
{
Write-Host "Starting the cache cluster..."
Start-CacheCluster
}
}
function SetCacheConnectionString {
param ([string] $provider, [string] $newConnectionString)
Write-Host "Parameters: " $provider " " $newConnectionString
$powerShell = [System.Management.Automation.PowerShell]::Create()
# Import the admin cmdlets module
$powerShell.AddCommand("Import-Module", $true);
$powerShell.AddParameter("Name", "DistributedCacheAdministration")
# Call the Invoke method to run the commands
$powerShell.Invoke();
$powerShell.Commands.AddCommand("Use-CacheCluster")
$powerShell.Commands.AddCommand("Get-CacheHost")
$commandResults = $powerShell.Invoke()
$powerShell.Dispose()
Write-Host "Number of hosts in the cluster " $commandResults.Count
foreach ($cacheHost in $commandResults)
{
Write-Host "Configuring the host " $cacheHost.HostName
Invoke-Command -ComputerName $cacheHost.HostName -ScriptBlock {param ($provider, $newConnectionString) Import-Module DistributedCacheConfiguration;Remove-CacheHost;Add-CacheHost -Provider $provider -ConnectionString $newConnectionString -Account 'NT Authority\NETWORK SERVICE'} -ArgumentList $provider, $newConnectionString
}
}
#
# Entry
#
Main
I am new to PowerShell and am trying to write a URL extension brute-force tool. My current target that I am testing against is a SharePoint site. I can manually, using a browser, go to the default homepage (the only URL I am currently testing against), but I get a 401 status code when I try from my script.
Here is my code:
#$d equals the domain name for the website
#$i equals the input location and filename for the url list
#$o equals the output location and filename for the output
param(
[parameter(mandatory=$true)]
[validatenotnull()]
$d = $(throw "please provide the domain of the target URL. Ex https://www.google.com"),
[parameter(mandatory=$true]
[validatenotnull()]
$i = $(throw "Please provide the path to the file listing the URL extensions."),
[string]
$o
)
$date = (get-date -format MM-dd-yy)
$cert = (get-childitem cert: -recurse | where {$_ -is [system.security.cryptography.x509certificates.x509certificate2]})
if ($o -eq "") {
$o = $date+"_output.txt"
new-item -path .\ -name $o -type file
}
cls
get-content $i |
foreach-object {
try {invoke-webrequest -url $d$_ -certificate $cert -method head -maximumredirection 0}
catch {"error - $_"}
echo ($_)
echo ""
echo "-----------------------------------------------------------------"
} | tee -a $o
The error I am getting back is the following:
Error - Cannot convert 'System.Object[]' to the type 'System.Security.Cryptography.X509Certificates.X509Certificate' required by parameter 'Certificate'. Specified method is not supported.
I am running windows 7 and PowerShell v3.
I have a question i wrote a powershell script so i have name.ps1, but i have troubles for executing it, i mean i could debut it with windows powershell (ISE), by just adding the code to it and run ... but how do i execute it different?
When i open ordinary windows powershell (so NOT ISE) and i type there script.ps1 file.csv
i get this kind of error:
This is the code that i have, maybe im not proper initiating the script in my code i dont know:
param ([string]$Csv)
function GetHelp() {
$HelpText = #"
DESCRIPTION:
NAME: Add-STUser
Adds Users from the User Csv File
PARAMETERS:
-Csv The Csv file Used by the script (Required)
-help Prints the HelpFile (Optional)
The Csv File is built up in the following way:
Firstname, Surname, Email
"#
$HelpText
}
function Get-Csv ([string]$Csv) {
$CsvFile = Import-Csv $Csv
$CsvFile | ForEach {
Add-User -Firstname $_.Firstname -Surname $_.Surname -Email $_.Email
}
}
function Add-User ([string]$Firstname, [string]$Surname, [string]$Email) {
# Set up AD Connectionstring
# Get A Unique Password
[string]$Password = Generate-Password
$username=$Firstname.substring(0,1).toLower() + $Surname.toLower()
# Create User in AD
$container =[ADSI] $Connection
$User = $container.Create("User", "cn="+$username)
$User.Put("sAMAccountName", $username)
$User.Put("givenName", $Firstname)
$User.Put("sn", $Surname)
$User.Put("mail", $Email)
$User.Put("displayName", $Firstname + " "+$Surname)
$User.SetInfo()
# Set Random Pwd and Enable Account
$User.PsBase.Invoke("SetPassword", $Password)
$User.PsBase.InvokeSet("AccountDisabled", $false)
$User.pwdLastSet = 0
$User.SetInfo()
# Write Pwd to File
$FileName = "PasswordList " + (get-date -uformat "%Y-%m-%d") + ".txt"
"$Firstname, $Surname, $username, $email, $Password" | Add-Content $FileName
Write-Host "Added User: $username" -ForegroundColor Green
# Set Check Variable to False
$Password = $Null
#$Script:sAMAccountNameDoesntExist = $False
#$Script:distinguishedNameDoesntExist = $False
}
if ($help) {
GetHelp
} elseif ($Domain -AND $Csv) {
Get-Csv -Csv $Csv
} else {
GetHelp
}
So with other words i need to execute that script with only 1 param (path to csv file)
Thanks in advance
In Powershell, unlike cmd, current directory (.) is not in PATH.
So to run scripts or executables in the current directory, you have to prefix with ./
So you will have to do
.\script.ps1 file.csv
If you look carefully at the error message, at the bottom, Powershell is giving a suggestion that you have to do so.
You need to tell Powershell you want to execute a script from current location, like in *nix systems. So call the script like the error message hints:
./myScript.ps1
or
.\myScript.ps1
You can also provide full path to the script
c:\what\ever\is\the\path\myScript.ps1
The script/directory names are not case sensitive.