Get all users from Yammer with REST API - yammer

I found this blog on how to get all users with REST however I am receiving an error:
PS C:\windows\system32> C:\Temp\YammerUsers.ps1
https://www.yammer.com/api/v1/users.json?page=1
https://www.yammer.com/api/v1/users.json?page=1 System.Collections.ArrayList
The '++' operator works only on numbers. The operand is a 'System.Object[]'.
At C:\Temp\YammerUsers.ps1:34 char:16
+ return Get-YamUsers($page++, $allUsers)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : OperatorRequiresNumber
Code is as follows:
$baererToken = "TOKEN REMOVED"
$yammerBaseUrl = "https://www.yammer.com/api/v1"
Function Get-BaererToken() {
$headers = #{ Authorization=("Bearer " + $baererToken) }
return $headers
}
Function Get-YamUsers($page, $allUsers) {
if ($page -eq $null) {
$page = 1
}
if ($allUsers -eq $null) {
$allUsers = New-Object System.Collections.ArrayList($null)
}
$urlToCall = "$($yammerBaseUrl)/users.json"
$urlToCall += "?page=" + $page
$headers = Get-BaererToken
Write-Host $urlToCall
$webRequest = Invoke-WebRequest –Uri $urlToCall –Method Get -Headers
$headers
if ($webRequest.StatusCode -eq 200) {
$results = $webRequest.Content | ConvertFrom-Json
if ($results.Length -eq 0) {
return $allUsers
}
$allUsers.AddRange($results)
}
if ($allUsers.Count % 50 -eq 0) {
return Get-YamUsers($page++, $allUsers)
}
else {
return $allUsers
}
}
$users = Get-YamUsers
$users | Select-Object id, email
$page isn't an integer so can't be incremented but I am unable to find how to edit this code to make it work. Any thoughts?

You can use this API to get all the users in Yammer Network.
https://www.yammer.com/api/v1/users.json

Try dynamic casting in PowerShell to increment $Page.
Replace:
return Get-YamUsers($page++, $allUsers)
With:
return Get-YamUsers(([int]$page)++, $allUsers)

The correct code is here
$baererToken = "put your api token here"
$yammerBaseUrl = "https://www.yammer.com/api/v1"
Function Get-BaererToken() {
$headers = #{ Authorization=("Bearer " + $baererToken) }
return $headers
}
Function Get-YamUsers($page, $allUsers) {
if ($page -eq $null) {
$page = 1
}
if ($allUsers -eq $null) {
$allUsers = New-Object System.Collections.ArrayList($null)
}
$urlToCall = $yammerBaseUrl + "/users.json?page=" + $page
Write-Host $urlToCall
$headers = Get-BaererToken
$webRequest = Invoke-WebRequest –Uri $urlToCall –Method Get -Headers $headers
if ($webRequest.StatusCode -eq 200) {
$results = $webRequest.Content | ConvertFrom-Json
if ($results.Length -eq 0) {
return $allUsers
}
$allUsers.AddRange($results)
}
if ($allUsers.Count % 50 -eq 0) {
write-host $page
return Get-YamUsers -page ($page+1) -allUsers $allUsers
}
else {
return $allUsers
}
}
$users = Get-YamUsers
$users | Select-Object id, email, state, jobtitle, location, full_name, first_name, lastname, network_name | Export-Csv -Path C:\exported_users.csv -NoTypeInformation -Encoding UTF8

Related

how to create a thumbnail while saving the image

i have this code where the user uploaded image is saved.
is it possible in the meantime to create a thumbnail?
function saveImages($dataArray, $idArticles, $folderPath, $prefixFile){
$folderPathDefault = '../../media/articles/imm'.$idArticles.'/';
$prefixFileDefault = 'photo_';
if($folderPath == null){
$folderPath = $folderPathDefault;
array_map('unlink', array_filter((array) glob($folderPath."*")));
}
if($prefixFile == null){
$prefixFile = $prefixFileDefault;
}
if (!is_dir($folderPath)) {
// dir doesn't exist, make it
mkdir($folderPath);
}
$count = 1;
foreach ($dataArray as $data) {
$image_parts = explode(";base64,", $data);
$image_type_aux = explode("image/", $image_parts[0]);
$image_type = $image_type_aux[1];
$image_base64 = base64_decode($image_parts[1]);
$file = $folderPath . $prefixFile . $count . '.jpg';
file_put_contents($file, $image_base64);
$count ++;
}
}
Thank you
For those interested or solved with this function:
function resize_image($file, $w, $h, $crop=FALSE) {
list($width, $height) = getimagesize($file);
$r = $width / $height;
if ($crop) {
if ($width > $height) {
$width = ceil($width-($width*abs($r-$w/$h)));
} else {
$height = ceil($height-($height*abs($r-$w/$h)));
}
$newwidth = $w;
$newheight = $h;
} else {
if ($w/$h > $r) {
$newwidth = $h*$r;
$newheight = $h;
} else {
$newheight = $w/$r;
$newwidth = $w;
}
}
$src = imagecreatefromjpeg($file);
$dst = imagecreatetruecolor($newwidth, $newheight);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
return $dst;
}
function saveImages($dataArray, $idArticles, $folderPath, $prefixFile){
$folderPathDefault = '../../media/articles/imm'.$idArticles.'/';
$prefixFileDefault = 'photo_';
if($folderPath == null){
$folderPath = $folderPathDefault;
array_map('unlink', array_filter((array) glob($folderPath."*")));
}
if($prefixFile == null){
$prefixFile = $prefixFileDefault;
}
if (!is_dir($folderPath)) {
// dir doesn't exist, make it
mkdir($folderPath);
}
$count = 1;
foreach ($dataArray as $data) {
$image_parts = explode(";base64,", $data);
$image_type_aux = explode("image/", $image_parts[0]);
$image_type = $image_type_aux[1];
$image_base64 = base64_decode($image_parts[1]);
$file = $folderPath . $prefixFile . $count . '.jpg';
file_put_contents($file, $image_base64);
$count ++;
}
if (!file_exists('../../media/articles/imm'.$idArticles.'/thumbnail/')) {
mkdir('../../media/articles/imm'.$idArticles.'/thumbnail/', 0777, true);
}
$dir = "../../media/articles/imm".$idArticles."/thumbnail/";
array_map('unlink', glob("{$dir}*.jpg"));
$immagine= "../../media/articles/imm".$idArticles."/";
$files = glob("$immagine*.*");
$uno= 1;
for ($i=0; $i<count($files); $i++) {
$image = $files[$i];
$url = $image;
$imgResize = resize_image($url, 360, 270);
$path = '../../media/articles/imm'.$idArticles.'/thumbnail/thumbnail_photo_'.$uno++.'.jpg';
imagejpeg($imgResize, $path);
}
}

Laravel chunk filter collection

Actually i have a simple collection but i need to make a filter to this collection and the filter call GoogleMaps to determine the distance between origin and destination, the problem is that i have more than 100 row $arbitres and this part of the process is getting very very very long.
How could i do to get more performance ?
I would like to try chunk but a get
Method newQuery does not exist.
`
here my method to get the collection :
$arbitres = Licencies::getArbitres($rencontre->dt_rencontre);
public static function getArbitres($date){
$licences = Licencies::whereIn('activite_licencie_id' , [24,25,50,80])
->where('valid_licence_id' , 3)
->where('saison_id' , self::getSaison()->id)
->where('dispo' , 1)
->whereHas('fonctions')
->whereHas('divisions')
->whereDoesntHave('rencontreOfficiels', function ($query) use ($date) {
$query->where('dt_rencontre', $date);
})->get();
return $licences;
}
here my process who is getting so long : ('m doing this in order to filter $arbitres with the shortest distance.
for($i=0; $i <= 1200 ; $i+=200){
$geo_filter = $arbitres->filter(function ($arbitre) use ($rencontre , $i) {
$origin = $arbitre->lb_adresse .' '. $arbitre->lb_ville_naissance .' '. $arbitre->cd_dept_naissance;
$destination = $rencontre->stade->adresse_stade .' '. $rencontre->stade->ville_stade .' '. $rencontre->stade->cd_post_stade;
$distance = getDistance($origin, $destination);
$distance = (float)$distance;
if($distance <= $i){
return true;
}
return false;
});
if ($geo_filter->isNotEmpty()) {
$arbitres = $geo_filter;
break;
}
}
fonction getdistance :
function getDistance($origin, $destination){
$distance = 0;
$response = \GoogleMaps::load('directions')
->setParam([
'origin' => $origin,
'destination' => $destination,
'mode' => 'driving' ,
'language' => 'fr',
])->get();
$parsed_json = (json_decode($response));
if($parsed_json->status != "NOT_FOUND") {
$result = $parsed_json->{'routes'}[0]->{'legs'}[0]->{'distance'}->{'text'};
$a = $result;
$b = str_replace(" km",'',$a);
$distance = str_replace(",",'.',$b);
}
if(is_numeric($distance)){
$distance = $distance * 2;
}
return $distance;
}

Elasticsearch query is extremely slow and not efficient

I am new to the elastic search concept and I am exposed to this concept because of a tool. This tool has now introduced Elasticsearch for fetching the license usage details of the tool user.
The version of elastic search installed is 6.4.3. The product by default provides a Powershell script which i have tried to add few filters to fetch the license consumption by dates and feature.
I would require to publish a report with the license consumption details every month. The below Powershell script does not finish executing even after 12 hours and the output file size is greater than 2 GB and still growing.
Any help in fine tuning this script would be of great help.
I use a batch file with the below content:
powershell.exe -File .\query.ps1 -hostname "<XXX>" -port 9200 -outputFilePath D:\LicenseUsageTracker\OutputFile.json -startDate 2019-12-10 -endDate 2019-12-11 -featureName XXX
The content of query.ps1 is as follows
param( [String]$hostname, [Int32]$port, [String]$outputFilePath, [STRING]$startDate, [STRING]$endDate ,$featureName)
function CheckStatusCode {
param( [Microsoft.PowerShell.Commands.HtmlWebResponseObject]$response )
if ($response.StatusCode -ne 200) {
Write-host ("ERROR RESPONSE: STATUS: " + ($response.StatusCode) + "; CONTENT: " + ($response.Content | ConvertFrom-Json | ConvertTo-Json))
return $false;
}
return $true;
}
function AddHits {
param( [System.Object[]]$hits, [String]$path )
If (-not (Test-Path $path -PathType Leaf)) {
New-Item $path -ItemType file -Force
}
$comma = "";
Write-host ("Writing " + $hits.length + " search results...")
ForEach ($hit In $hits) {
Add-Content -Path $path -Value ($comma + ($hit._source | ConvertTo-Csv -NoTypeInformation))
$comma = "";
}
Write-host ("done.")
}
If (Test-Path $outputFilePath -PathType Leaf) {
$overwrite = read-host ("File '" + $outputFilePath + "' exists already. Overwrite? (yes/no)");
If ($overwrite -ne "yes") {
Write-host ("Exiting script.")
return;
} else {
Write-host ("Overwriting file '" + $outputFilePath + "'");
Remove-Item -Path $outputFilePath
}
} else {
Write-host ("Writing to file '" + $outputFilePath + "'");
}
$response = Invoke-WebRequest -Uri "http://${hostname}:${port}/usageinfo/_search?scroll=2m&filter_path=_scroll_id,hits.hits._source" -ContentType "application/json" -Method POST -Body ('{
"query": {
"bool": {
"must": [
{
"range": {
"timeStamp": {
"gte": "' + $startDate + '",
"lte": "' + $endDate + '"
}
}
},
{
"match": {
"featureName":"' + $featureName + '"
}
}
]
}
},
"size": 10000
}');
if (-not (CheckStatusCode($response))) {
return;
}
$jsonContent = ($response.Content | ConvertFrom-Json);
$scrollId = $jsonContent._scroll_id;
$hits = $jsonContent.hits.hits;
AddHits $hits $outputFilePath;
while ($hits.length -gt 0) {
$response = Invoke-WebRequest -Uri "http://${hostname}:${port}/_search/scroll?filter_path=_scroll_id,hits.hits._source" -ContentType "application/json" -Method POST -Body ('{ "scroll" : "2m", "scroll_id" : "' + $scrollId + '"}');
if (-not (CheckStatusCode($response))) {
return;
}
$scrollId = ($response.Content | ConvertFrom-Json)._scroll_id;
$hits = ($response.Content | ConvertFrom-Json).hits.hits;
If ($hits.Length -ne 0) {
AddHits $hits $outputFilePath;
}
};

Passing URL parameters as command line script arguments security considerations

I am writing a web app and I need to pass some url parameters as command line arguments to another script. What should I do to avoid security problems? I am using Sympfony's Process to execute the bash command and Laravel to build the app.
Here is some of the code, look into the buildScreenshotCommand to see how I am building the command string and also note that the $urlRequest is filled in using the Laravel's Request $request class:
<?php
namespace App\Logic;
use App\Logic\TimeHelper;
use App\UrlRequest;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
class Screenshot {
static function take(UrlRequest $urlRequest)
{
$name = self::generateName($urlRequest);
$command = self::buildScreenshotCommand($name, $urlRequest);
$startTime = TimeHelper::milliseconds();
$process = new Process($command);
$process->run();
$endTime = TimeHelper::milliseconds();
if (!$process->isSuccessful())
{
throw new ProcessFailedException($process);
}
$output = $process->getOutput();
if (trim($output) === '')
{
$urlRequest->successful = 1;
$file = self::uploadToS3($name);
$urlRequest->image_url = $file['url'];
$urlRequest->file_size = $file['size'];
$urlRequest->file_name = $name;
$urlRequest->time_it_took_to_take_screenshot_ms = $endTime - $startTime;
if ($urlRequest->save())
{
return $urlRequest;
}
}
else
{
$urlRequest->error = $output;
$urlRequest->save();
}
return false;
}
static function uploadToS3($name)
{
$name = 'screenshots/' . $name;
Storage::disk('s3')->put($name, Storage::disk('local')->get($name), ['visibility' => 'public']); // upload to S3
$fileSize = Storage::disk('local')->size($name);
Storage::disk('local')->delete($name);
return [
'url' => Storage::disk('s3')->url($name),
'size' => $fileSize
];
}
static function generateName($urlRequest)
{
$name = time() . rand(10000, 99999);
$extension = '.png';
if (isset($urlRequest->pdf) AND $urlRequest->pdf == 1)
{
$extension = '.pdf';
}
while (UrlRequest::where('file_name', '=', $name . $extension)->first())
{
$name = time() . rand(10000, 99999);
}
return $name . $extension;
}
static function buildScreenshotCommand($name, $urlRequest)
{
$command = 'cd ' . base_path() . ' && node puppeteer-screenshots-init.js ';
$command .= "--url={$urlRequest->url} ";
$fullPath = storage_path('app') . '/screenshots/' . $name;
$command .= "--path={$fullPath} ";
if (isset($urlRequest->pdf))
{
$command .= "--pdf=true ";
}
if (isset($urlRequest->viewport_width))
{
$command .= "--viewportWidth={$urlRequest->viewport_width} ";
}
if (isset($urlRequest->mobile))
{
$command .= '--mobile=true ';
}
if (isset($urlRequest->media_type_print))
{
$command .= '--mediaTypePrint=true ';
}
if (isset($urlRequest->user_agent))
{
$command .= '--userAgent="' . $urlRequest->user_agent . '" ';
}
$command .= '2>&1 &';
return $command;
}
}
I think this is a really bad idea. What if $urlRequest->url was:
// urlencoded
http%3A%2F%2Fgoogle.com%3F%3Brm+-Rf+%2F%3B
http://google.com?;rm -Rf /;
What kind of input sanitization are you doing?

Getting Error (Microsoft Web Deploy v3 or higher is recommended.. )while using the build arguments in TFS build definition

Created a build definition using TFS 2013 to run a scheduled build.
And using SetupSiteForPublish.ps1(see below) in post-build script process to deploy the site on iis on a remote server.
I am referring following 2 articles:
Article1
Article2
Now When i use /P:CreatePackageOnPublish=True /P:DeployOnBuild=True
in MSBuild Arguments, getting following error message:
C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.targets
(3739): Package/Publish task
Microsoft.Web.Publishing.Tasks.IsCleanMSDeployPackageNeeded failed to
load Web Deploy assemblies. Microsoft Web Deploy is not correctly
installed on this machine. Microsoft Web Deploy v3 or higher is
recommended.
param(
[parameter(Mandatory = $false)]
$siteName,
[parameter(Mandatory = $false)]
$sitePhysicalPath,
[parameter(Mandatory = $false)]
$siteAppPoolName,
[parameter(Mandatory = $false)]
[int]$sitePort,
[parameter(Mandatory = $false)]
$deploymentUserName,
[parameter(Mandatory = $false)]
$deploymentUserPassword,
[parameter(Mandatory = $false)]
$managedRunTimeVersion,
[parameter(Mandatory = $false)]
$publishSettingSavePath,
[parameter(Mandatory = $false)]
$publishSettingFileName
)
##Import-LocalizedData -BindingVariable Resources -FileName Resources.psd1
# ==================================
#constants
$SCRIPTERROR = 0
$WARNING = 1
$INFO = 2
$logfile = ".\HostingLog-$(get-date -format MMddyyHHmmss).log"
$template = #"
<?xml version="1.0" encoding="utf-8"?>
<publishData>
<publishProfile
publishUrl=""
msdeploySite=""
destinationAppUrl=""
mySQLDBConnectionString=""
SQLServerDBConnectionString=""
profileName="Default Settings"
publishMethod="MSDeploy"
userName=""
userPWD=""
savePWD="True"
/>
</publishData>
"#
#the order is important. Check for apppool name first. Its possible that
#the user gave just a sitename to set permissions. In this case leave apppool emtpy.
#else give a default name to the apppool.
if(!$siteAppPoolName)
{
if(!$siteName)
{
$siteAppPoolName = "AvailabilityServiceAgent"
}
}
else
{
$siteAppPoolName = $siteAppPoolName.Trim()
}
#now the sitename check. If its empty give it a default name
if(!$siteName)
{
$siteName = "AvailabilityServiceAgent"
}
else
{
$siteName = $siteName.Trim()
}
if(!$sitePhysicalPath)
{
$sitePhysicalPath= $ENV:TF_BUILD_DROPLOCATION+"\_PublishedWebsites\AvailabilityServiceHost"
}
else
{
$sitePhysicalPath = $sitePhysicalPath.Trim()
}
#global variable. Because we need to return two values from MWA from one function. [REF] has bugs. Hence global
$global:sitePath = $sitePhysicalPath
$global:publishURL = $null
# this function does logging
function write-log([int]$type, [string]$info){
$message = $info -f $args
$logMessage = get-date -format HH:mm:ss
Switch($type){
$SCRIPTERROR{
$logMessage = $logMessage + "`t" + $Resources.Error + "`t" + $message
write-host -foregroundcolor white -backgroundcolor red $logMessage
}
$WARNING{
$logMessage = $logMessage + "`t" + $Resources.Warning + "`t" + $message
write-host -foregroundcolor black -backgroundcolor yellow $logMessage
}
default{
$logMessage = $logMessage + "`t" + $Resources.Info + "`t" + $message
write-host -foregroundcolor black -backgroundcolor green $logMessage
}
}
$logMessage >> $logfile
}
function GetPublishSettingSavePath()
{
if(!$publishSettingFileName)
{
$publishSettingFileName = "WDeploy.PublishSettings"
}
if(!$publishSettingSavePath)
{
$publishSettingSavePath = [System.Environment]::GetFolderPath("Desktop")
}
if((test-path $publishSettingSavePath) -eq $false)
{
write-log $SCRIPTERROR $Resources.FailedToAccessScriptsFolder $publishSettingSavePath
return $null
}
return Join-Path $publishSettingSavePath $publishSettingFileName
}
# returns false if OS is not server SKU
function NotServerOS
{
$sku = $((gwmi win32_operatingsystem).OperatingSystemSKU)
$server_skus = #(7,8,9,10,12,13,14,15,17,18,19,20,21,22,23,24,25)
return ($server_skus -notcontains $sku)
}
# gives a user access to an IIS site's scope
function GrantAccessToSiteScope($username, $websiteName)
{
trap [Exception]
{
write-log $SCRIPTERROR $Resources.FailedToGrantUserAccessToSite $username $websiteName
return $false
}
foreach($mInfo in [Microsoft.Web.Management.Server.ManagementAuthorization]::GetAuthorizedUsers($websiteName, $false, 0,[int]::MaxValue))
{
if($mInfo.Name -eq $username)
{
write-log $INFO $Resources.UserHasAccessToSite $username $websiteName
return $true
}
}
[Microsoft.Web.Management.Server.ManagementAuthorization]::Grant($username, $websiteName, $FALSE) | out-null
write-log $INFO $Resources.GrantedUserAccessToSite $username $websiteName
return $true
}
# gives a user permissions to a file on disk
function GrantPermissionsOnDisk($username, $type, $options)
{
trap [Exception]
{
write-log $SCRIPTERROR $Resources.NotGrantedPermissions $type $username $global:sitePath
}
$acl = (Get-Item $global:sitePath).GetAccessControl("Access")
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule($username, $type, $options, "None", "Allow")
$acl.AddAccessRule($accessrule)
set-acl -aclobject $acl $global:sitePath
write-log $INFO $Resources.GrantedPermissions $type $username $global:sitePath
}
function AddUser($username, $password)
{
if(-not (CheckLocalUserExists($username) -eq $true))
{
$comp = [adsi] "WinNT://$env:computername,computer"
$user = $comp.Create("User", $username)
$user.SetPassword($password)
$user.SetInfo()
write-log $INFO $Resources.CreatedUser $username
}
}
function CheckLocalUserExists($username)
{
$objComputer = [ADSI]("WinNT://$env:computername")
$colUsers = ($objComputer.psbase.children | Where-Object {$_.psBase.schemaClassName -eq "User"} | Select-Object -expand Name)
$blnFound = $colUsers -contains $username
if ($blnFound){
return $true
}
else{
return $false
}
}
function CheckIfUserIsAdmin($username)
{
$computer = [ADSI]("WinNT://$env:computername,computer")
$group = $computer.psbase.children.find("Administrators")
$colMembers = $group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name",'GetProperty',$null,$_,$null)}
$bIsMember = $colMembers -contains $username
if($bIsMember)
{
return $true
}
else
{
return $false
}
}
function CreateLocalUser($username, $password, $isAdmin)
{
AddUser $username $password
if($isAdmin)
{
if(-not(CheckIfUserIsAdmin($username) -eq $true))
{
$group = [ADSI]"WinNT://$env:computername/Administrators,group"
$group.add("WinNT://$env:computername/$username")
write-log $INFO $Resources.AddedUserAsAdmin $username
}
else
{
write-log $INFO $Resources.IsAdmin $username
}
}
return $true
}
function Initialize
{
trap [Exception]
{
write-log $SCRIPTERROR $Resources.CheckIIS7Installed
break
}
$inetsrvPath = ${env:windir} + "\system32\inetsrv\"
[System.Reflection.Assembly]::LoadFrom( $inetsrvPath + "Microsoft.Web.Administration.dll" ) > $null
[System.Reflection.Assembly]::LoadFrom( $inetsrvPath + "Microsoft.Web.Management.dll" ) > $null
}
function GetPublicHostname()
{
$ipProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
if($ipProperties.DomainName -eq "")
{
return $ipProperties.HostName
}
else
{
return "{0}.{1}" -f $ipProperties.HostName, $ipProperties.DomainName
}
}
function GenerateStrongPassword()
{
[System.Reflection.Assembly]::LoadWithPartialName("System.Web") > $null
return [System.Web.Security.Membership]::GeneratePassword(12,4)
}
function GetPublishURLFromBindingInfo($bindingInfo, $protocol, $hostname)
{
$port = 80
trap [Exception]
{
#return defaults
return "http://$hostname"
}
if(($bindingInfo -match "(.*):(\d*):([^:]*)$") -and
($Matches.Count -eq 4 ))
{
$port = $Matches[2]
$header = $Matches[3]
$ipaddress = $Matches[1]
if($header)
{
$hostname = $header
}
elseif(($ipaddress) -AND (-not($ipaddress -eq "*")))
{
$bracketsArray = #('[',']')
$hostname = $ipaddress.Trim($bracketsArray)
}
if(-not($port -eq 80))
{
$hostname = $hostname + ":" + $port
}
}
return $protocol + "://" + $hostname
}
function GetUnusedPortForSiteBinding()
{
[int[]] $portArray = $null
$serverManager = (New-Object Microsoft.Web.Administration.ServerManager)
foreach($site in $serverManager.Sites)
{
foreach($binding in $site.Bindings)
{
if($binding.IsIPPortHostBinding)
{
if($binding.Protocol -match "https?")
{
if(($binding.BindingInformation -match "(.*):(\d*):([^:]*)$") -and
($Matches.Count -eq 4 ))
{
$portArray = $portArray + $Matches[2]
}
}
}
}
}
if(-not($portArray -eq $null))
{
$testPortArray = 8081..8200
foreach($port in $testPortArray)
{
if($portArray -notcontains $port)
{
return $port
}
}
}
return 8081 #default
}
function CreateSite($name, $appPoolName, $port, $dotnetVersion)
{
trap [Exception]
{
write-log $SCRIPTERROR $Resources.SiteCreationFailed
return $false
}
$hostname = GetPublicHostName
$global:publishURL = "http://$hostname"
if(-not($port -eq 80))
{
$global:publishURL = $global:publishURL + ":" + $port
}
$configHasChanges = $false
$serverManager = (New-Object Microsoft.Web.Administration.ServerManager)
#appPool might be empty. WHen the user gave just a site name to
#set the permissions on. As long as the sitename is not empty
if($appPoolName)
{
$appPool = $serverManager.ApplicationPools[$appPoolName]
if ($appPool -eq $null)
{
$appPool = $serverManager.ApplicationPools.Add($appPoolName)
$appPool.Enable32BitAppOnWin64 = $true
if( ($dotnetVersion) -and
(CheckVersionWithinAllowedRange $dotnetVersion) )
{
$appPool.ManagedRuntimeVersion = $dotnetVersion
}
$configHasChanges = $true
write-log $INFO $Resources.AppPoolCreated $appPoolName
}
else
{
write-log $WARNING $Resources.AppPoolExists $appPoolName
}
}
$newSite = $serverManager.Sites[$name]
if ($newSite -eq $null)
{
$newSite = $serverManager.Sites.Add($name,$global:sitePath, $port)
$newSite.Applications[0].ApplicationPoolName = $appPool.Name
if((test-path $global:sitePath) -eq $false)
{
[System.IO.Directory]::CreateDirectory($global:sitePath)
}
else
{
write-log $WARNING $Resources.SiteVirtualDirectoryExists $global:sitePath
}
$newSite.ServerAutoStart = $true
$configHasChanges = $true
write-log $INFO $Resources.SiteCreated $name
}
else
{
#get virtual directory and siteport
$global:sitePath = [System.Environment]::ExpandEnvironmentVariables($newSite.Applications["/"].VirtualDirectories["/"].PhysicalPath)
foreach($binding in $newSite.Bindings)
{
if($binding.IsIPPortHostBinding)
{
if($binding.Protocol -match "https?")
{
$global:publishURL = GetPublishURLFromBindingInfo $binding.BindingInformation $binding.Protocol $hostname
}
}
}
if($appPoolName)
{
if (-not($newSite.Applications[0].ApplicationPoolName -eq $appPool.Name ))
{
$newSite.Applications[0].ApplicationPoolName = $appPool.Name
write-log $INFO $Resources.SiteAppPoolUpdated $name $appPoolName
}
else
{
write-log $INFO $Resources.SiteExists $name $appPoolName
}
}
else
{
write-log $INFO $Resources.SiteExists $name $newSite.Applications[0].ApplicationPoolName
}
}
if ($configHasChanges)
{
$serverManager.CommitChanges()
}
return $true
}
function CheckUserViaLogon($username, $password)
{
$signature = #'
[DllImport("advapi32.dll")]
public static extern int LogonUser(
string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
'#
$type = Add-Type -MemberDefinition $signature -Name Win32Utils -Namespace LogOnUser -PassThru
[IntPtr]$token = [IntPtr]::Zero
$value = $type::LogOnUser($username, $env:computername, $password, 2, 0, [ref] $token)
if($value -eq 0)
{
return $false
}
return $true
}
function CheckUsernamePasswordCombination($user, $password)
{
if(($user) -AND ($password))
{
if(CheckLocalUserExists($user) -eq $true)
{
if(CheckUserViaLogon $user $password)
{
return $true
}
else
{
write-Log $SCRIPTERROR $Resources.FailedToValidateUserWithSpecifiedPassword $user
return $false
}
}
}
return $true
}
function CreateProfileXml([string]$nameofSite, [string]$username, $password, [string]$hostname, $pathToSaveFile)
{
trap [Exception]
{
write-log $SCRIPTERROR $Resources.FailedToWritePublishSettingsFile $pathToSaveFile
return
}
$xml = New-Object xml
if(Test-Path $pathToSaveFile)
{
$xml.Load($pathToSaveFile)
}
else
{
$xml.LoadXml($template)
}
$newProfile = (#($xml.publishData.publishProfile)[0])
$newProfile.publishUrl = $hostname
$newProfile.msdeploySite = $nameofSite
$newProfile.destinationAppUrl = $global:publishURL.ToString()
$newProfile.userName = $username
if(-not ($password -eq $null))
{
$newProfile.userPWD = $password.ToString()
}
else
{
write-log $WARNING $Resources.NoPasswordForExistingUserForPublish
}
$xml.Save($pathToSaveFile)
write-log $INFO $Resources.SavingPublishXmlToPath $pathToSaveFile
}
function CheckVersionWithinAllowedRange($managedVersion)
{
trap [Exception]
{
return $false
}
$KeyPath = "HKLM:\Software\Microsoft\.NETFramework"
$key = Get-ItemProperty -path $KeyPath
$path = $key.InstallRoot
$files = [System.IO.Directory]::GetFiles($path, "mscorlib.dll", [System.IO.SearchOption]::AllDirectories)
foreach($file in $files)
{
if($file -match "\\(v\d\.\d).\d*\\")
{
if($Matches[1] -eq $managedVersion)
{
return $true
}
}
}
return $false
}
#================= Main Script =================
if(NotServerOS)
{
write-log $SCRIPTERROR $Resources.NotServerOS
break
}
Initialize
if(CheckUsernamePasswordCombination $deploymentUserName $deploymentUserPassword)
{
if(!$sitePort)
{
$sitePort = GetUnusedPortForSiteBinding
}
if(CreateSite $siteName $siteAppPoolName $sitePort $managedRunTimeVersion)
{
if(!$deploymentUserName)
{
$idx = $siteName.IndexOf(' ')
if( ($idx -gt 0) -or ($siteName.Length -gt 16))
{
$deploymentUserName = "WDeployuser"
}
else
{
$deploymentUserName = $siteName + "user"
}
}
if( (CheckLocalUserExists($deploymentUserName) -eq $true))
{
$deploymentUserPassword = $null
}
else
{
if(!$deploymentUserPassword)
{
$deploymentUserPassword = GenerateStrongPassword
}
}
if(CreateLocalUser $deploymentUserName $deploymentUserPassword $false)
{
GrantPermissionsOnDisk $deploymentUserName "FullControl" "ContainerInherit,ObjectInherit"
if(GrantAccessToSiteScope ($env:computername + "\" + $deploymentUserName) $siteName)
{
$hostname = GetPublicHostName
$savePath = GetPublishSettingSavePath
if($savePath)
{
CreateProfileXml $siteName $deploymentUserName $deploymentUserPassword $hostname $savePath
}
}
}
}
}
Write-Host “Post-build script succeeded!”

Resources