2014. október 14., kedd

Can't install an additional Exchange 2013 in the domain

Today I've just run into this funny issue. It took two hours for me to get the clue!

Here is the error report:

Error:
Global updates need to be made to Active Directory, and this user account isn't a member of the 'Enterprise Admins' group.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.GlobalUpdateRequired.aspx

Error:
You must be a member of the 'Organization Management' role group or a member of the 'Enterprise Admins' group to continue.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.GlobalServerInstall.aspx

Error:
You must use an account that's a member of the Organization Management role group to install or upgrade the first Mailbox server role in the topology.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.DelegatedBridgeheadFirstInstall.aspx

Error:
You must use an account that's a member of the Organization Management role group to install the first Client Access server role in the topology.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.DelegatedCafeFirstInstall.aspx

Error:
You must use an account that's a member of the Organization Management role group to install the first Client Access server role in the topology.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.DelegatedFrontendTransportFirstInstall.aspx

Error:
You must use an account that's a member of the Organization Management role group to install or upgrade the first Mailbox server role in the topology.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.DelegatedMailboxFirstInstall.aspx

Error:
You must use an account that's a member of the Organization Management role group to install or upgrade the first Client Access server role in the topology.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.DelegatedClientAccessFirstInstall.aspx

Error:
You must use an account that's a member of the Organization Management role group to install the first Mailbox server role in the topology.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.DelegatedUnifiedMessagingFirstInstall.aspx

Error:
Setup encountered a problem while validating the state of Active Directory: Couldn't find the Enterprise Organization container.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.AdInitErrorRule.aspx

Error:
The forest functional level of the current Active Directory forest is not Windows Server 2003 native or later. To install Exchange Server 2013, the forest functional level must be at least Windows Server 2003 native.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.ForestLevelNotWin2003Native.aspx

Error:
Either Active Directory doesn't exist, or it can't be contacted.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.CannotAccessAD.aspx

Warning:
Setup will prepare the organization for Exchange 2013 by using 'Setup /PrepareAD'. No Exchange 2010 server roles have been detected in this topology. After this operation, you will not be able to install any Exchange 2010 servers.
For more information, visit: http://technet.microsoft.com/library(EXCHG.150)/ms.exch.setupreadiness.NoE14ServerWarning.aspx


Obviously, the AD was prepared previously (having a working Exchange 2013) and I'm a Schema and Enterprise Admin.
Solution:
It turned out that I was trying to install the Exchange in site A (a site with a working DC) but the the Schema Master FSMO role holder DC was located in site B. Of course both was perfectly connected and replicating with the other. However, for whatever reason my clever Exchange setup was simply unable to connect the Schema Master and exited in such a stupid way. I moved the Schema Master role to site A and voila, Exchange setup immediately worked.

2014. október 10., péntek

How to mass-upload profile pictures to Exchange 2013

It's friday afternoon, an hour before the end of your shift. Biggest boss walkes into your office and says:
- It's good to see you being so happy to see me. I've got a job for you. You gotta load our new employees' high-resolution photos into our company's Exchange2013 immediately. You should be able to find all the 180 picture files on the fileserver. Actualy, it should have done yesterday. So... (dramatic pause)... have you done it yet ?
  1. - Don't panic.
  2. - Resize or cut those freaking profile photos to 648x648 pixels with a free smart photo viewer, for example with a batch job in Irfanview.
  3. - Rename the files to match your users' login names, e.g. Bill Gates -- billgates.jpg - That's the trickiest part if your files are called user3412_10102014.png or whatever. That'd suck. Force your colleagues to name the files properly next time.
  4. - Use this script. It reads all the files in the sourcedir, takes the username from filename and puts the picture into that user's corresponding Exchange attribute.

$sourcedir = "c:\temp\photos\"
$files = Get-ChildItem $sourcedir -Filter "*.jpg"
$files | ForEach-Object {

   $fullpath= $sourcedir + $_.Name
   $name = $_.BaseName
   write $fullpath
   write $name

   $photo = ([Byte[]] $(Get-Content -Path $fullpath -Encoding Byte -ReadCount 0))
   Set-UserPhoto -Identity $name -PictureData $photo -Confirm:$False
   Set-UserPhoto -Identity $name -Save -Confirm:$False
  
}


Curious why 648x648 is that dimension exactly? Nobody knows. Frankly. The point is you will end up with 3 different sized picture stored for each account in your AD and Exchange 2013 and Lync 2013 or Sharepoint 2013 (if you have any)
  1. 48 x 48 pixels in AD thumbnailPhoto attribute field (If you upload a photo to Exchange 2013, Exchange will automatically create a 48 pixel by 48 pixel version of that photo and update the user's thumbnailPhoto attribute. Note, however, that the reverse is not true: if you manually update the thumbnailPhoto attribute in Active Directory the photo in the user's Exchange 2013 mailbox will not automatically be updated).
  2. 96 x 96 pixels for use in Microsoft Outlook 2013 Web App and Microsoft Outlook 2013
  3. 648 x 648 pixels for use in Lync 2013 and Sharepoint 2013

2014. június 10., kedd

Yet another ultimate howto: a collection of hotfixes for Exchange 2010 for Windows 2008 R2

Want to install Exch2k10 on a W2k8R2? You can save lots of time making use of these links before the installation.
Prereqs:
 (run powershell commands from here) : http://www.enterprisenetworkingplanet.com/datacenter/Installing-Exchange-2010-Step-by-Step-3877601.htm
Grab these files:
http://www.microsoft.com/en-US/download/details.aspx?id=40779 (.NET 4.51)
http://www.microsoft.com/en-us/download/details.aspx?id=17331 (KB974405-x64)
http://www.microsoft.com/en-us/download/details.aspx?id=17062 (Office 2010 filter pack)
http://thehotfixshare.net/board/index.php?autocom=downloads&req=download&code=confirm_download&id=12354 (KB982867-v2-x64)
http://thehotfixshare.net/board/index.php?autocom=downloads&req=download&code=confirm_download&id=12136 (KB977020-v2-x64)
http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=29092 (KB983440-x64)
http://www.microsoft.com/en-US/download/details.aspx?id=16335 (KB979099-x64)
http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=27109  (6.1: KB979744-v2-x64 )


Also, don't forget SP3 http://www.microsoft.com/en-us/download/details.aspx?id=36768 (just run it from command line:
C:\Admin\ex2010sp3>setup /mode:upgrade /installwindowscomponents
and UR5 http://www.microsoft.com/en-us/download/details.aspx?id=42001 .



2014. április 30., szerda

ULTIMATE howto for GIT with LDAP auth

There are lots of tutors on this subject but hardy any of them are straigtforward and up-to-date. For me, it took plenty of days to get this disguisting system work on a Debian. (BTW, SVN FTW :))
Note that there are two, I repeat two methods to work with a GIT server: webdav and git-http-backend.
Webdav is nicer and cheaper but it is true it has some drawbacks. 
In the following we will setup a version hosting and control system called git with http-backend and an authentication mechanism against an LDAP server. My internal domain name is ring.local and my external hostname is git.ring-of-fire.com
We will set up a gitweb to ease supervision.
In the end, entering https://git.ring-of-fire.com/web in a browser and having confirmed that you are a member of ring_developers_webadmin, you will have your gitweb console.
Then you enter https://git.ring-of-fire.com/git/YourMightyRepo in your GIT client and identify yourself to be a valid member of the ring_developers LDAP group. Then, successfully authorized... guess what.

What to do in a nutshell.
1
apt-get install....

ii apache2 2.2.22-13+deb7u1 i386 Apache HTTP Server metapackage 
ii apache2-mpm-worker 2.2.22-13+deb7u1 i386 Apache HTTP Server - high speed threaded model 
ii apache2-utils 2.2.22-13+deb7u1 i386 utility programs for webservers 
ii apache2.2-bin 2.2.22-13+deb7u1 i386 Apache HTTP Server common binary files 
ii apache2.2-common 2.2.22-13+deb7u1 i386 Apache HTTP Server common files 
ii git 1:1.7.10.4-1+wheezy1 i386 fast, scalable, distributed revision control system 
ii git-core 1:1.7.10.4-1+wheezy1 all fast, scalable, distributed revision control system (obsolete)
ii git-man 1:1.7.10.4-1+wheezy1 all fast, scalable, distributed revision control system (manual pages)
ii gitweb 1:1.7.10.4-1+wheezy1 all fast, scalable, distributed revision control system (web interface) 

2
root@git:/etc/apache2/sites-enabled# cat *  

ServerName git.ring-of-fire.com # real FQDN, IMPORTART!! for git's sake
 <VirtualHost *:80>
ServerAdmin webmaster@localhost

 DocumentRoot /var/www/default  
Options -Indexes -FollowSymLinks -MultiViews AllowOverride None 
ErrorLog ${APACHE_LOG_DIR}/zhttp-error.log 
LogLevel warn 
CustomLog ${APACHE_LOG_DIR}/zhttp-access.log combined 
# a default site with any kind of index.html or .htaccess  
 </VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@localhost 
DocumentRoot /var/www 
Options Indexes FollowSymLinks MultiViews AllowOverride All  
ErrorLog ${APACHE_LOG_DIR}/error.log 
LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined 
SSLEngine On 
SSLCertificateFile /etc/apache2/ssl/git_ring.crt 
SSLCertificateKeyFile /etc/apache2/ssl/git_ring.key 
SSLCACertificateFile /etc/apache2/ssl/git_ring_bundle.ca 
BrowserMatch "git" nokeepalive ssl-unclean-shutdown 
 # this https site is for the real use 
 </VirtualHost>

3
root@git:/etc# cat gitweb.conf
# path to git projects (<project>.git)
$projectroot = "/var/www/git"
;
....
This is the only parameter you need to change.

4
root@git:/etc/apache2/conf.d# cat git.conf 
SetEnv GIT_PROJECT_ROOT /var/www/git # check
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git /usr/lib/git-core/git-http-backend/ # check if this dir exists

<Directory "/usr/lib/git-core">
  Options +ExecCGI
  Allow From All
</Directory>

AliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$          /var/www/git/$1
AliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /var/www/git/$1
ScriptAliasMatch \
    "(?x)^/git/(.*/(HEAD | \
            info/refs | \
            objects/info/[^/]+ | \
            git-(upload|receive)-pack))$" \
    /usr/lib/git-core/git-http-backend/$1

<Location "/git/YourMightyREPO">
    AuthBasicProvider ldap
    AuthType Basic
    AuthzLDAPAuthoritative on
    AuthName "Git Server"
         AuthLDAPURL "ldap://YourLDAPServerIP:389/OU=YourADOU,DC=ring,DC=local?sAMAccountName?sub?(objectClass=*)" NONE
        AuthLDAPBindDN "CN=Your auth user name,cn=Users,dc=ring,dc=local"
        AuthLDAPBindPassword verysecretpassword
       Require ldap-group                 CN=ring_developers,OU=your_groups_container_OU,DC=ring,DC=local

</Location>


5
root@git:/etc/apache2/conf.d# cat gitweb.conf
Alias /web "/usr/share/gitweb/" # Check if /usr/share/gitweb there exists. Note the string /web

<Directory "/usr/share/gitweb">
    Options ExecCGI
    AllowOverride None
    AddHandler cgi-script .cgi
    DirectoryIndex gitweb.cgi
    Order deny,allow
    Allow from all

    AuthBasicProvider ldap
    AuthType Basic
    AuthzLDAPAuthoritative on
    AuthName "GITWEB for RING"
     AuthLDAPURL "ldap://YourLDAPserverIP:389/OU=your_users_container_OU,DC=ring,DC=local?sAMAccountName?sub?(objectClass=*)" NONE
    AuthLDAPBindDN "CN=Your LDAP bind user name,cn=Users,dc=ring,dc=local"
        AuthLDAPBindPassword verysecretpassword
        Require ldap-group CN=ring_developers_webadmin,OU=your_groups_container_OU,DC=ring,DC=local



6
Initialize, check and done.

root@git:/var/www/default# ls
index.html


root@git:/var/www/git# ls

mkdir YourMightyRepo && cd * && git --bare init
cd .. && chown www-data:www-data * -R
service apache2 restart
get-a-coffee


More totally useless and misleading info here: http://git-scm.com/docs/git-http-backend

2014. január 23., csütörtök

Email forwarding

More powershell fun

Setting forward-only to an internal address :
Set-Mailbox -Identity "Joe Cool" -ForwardingAddress "james@mydomain.com"
Setting deliver-and-forward to an internal address :
Set-Mailbox -Identity "Joe Cool" -ForwardingAddress "james@mydomain.com" -DeliverToMailboxAndForward $true
Setting forward to an external address :
New-MailContact -Name "Very Important Dick" -ExternalEmailAddress "dick@vip.com"
Set-Mailbox "Joe Cool" -ForwardingAddress "dick@vip.com"
Listing what mailboxes are set to forward :
Get-Mailbox -Filter { ForwardingAddress -like '*' } | select-object Name,ForwardingAddress,ForwardingSmtpAddress
Cancel any type of forwarding:
Set-Mailbox -Identity [our.user@mydomain.com] -DeliverToMailboxandforward $False -ForwardingSMTPAddress $Null -ForwardingAddress $Null
Mass canceling:
Get-Mailbox | Where {$_.RecipientType -eq “UserMailbox”} | Set-Mailbox -ForwardingSmtpAddress $null
 

2013. december 17., kedd

Microsoft Windows Server: READ ONLY Domain Controllers ?! Nooooo

RODC? That's one of the biggest fallacy in the IT I've ever seen. For those who don't know: that's some kind of domain controller to be placed in a branch office. That's an office where security is in question, where servers can easily be stolen.
RODC's don't have writeable LDAP DB locally so they forward all the login requests to a RWDC. Do you see how supersecured they are?

Here is where the mystification begin: RODCs still have cached passwords locally so in case hackers gain direct access to the local system passwords - theoretically - could be compromised.
And the most biggest terrible security risk: passwords and accounts still CAN BE reset, re-enabled or in any way modified against an RODC. In this case an RODC stupidly forward the request to a RWDC and of course RWDC will automatically commit and redistribute the changes because of the confidential relationship between them.
In short: "When the password is changed or reset against an RODC, the RODC will forward the change to a W2K8 RWDC and after that it will automatically inbound replicate the password using the "Replicate Single Object" method assuming the account for which the password was reset/changed is still allowed to be cached/stored."
See more info for example at http://social.technet.microsoft.com/Forums/windowsserver/en-US/198e7c6a-0541-43cf-803f-1259e66fdd80/how-to-know-readonly-domain-controller



2013. november 14., csütörtök

Keep your session id after redirect or reload

Ever wondered how to keep your original session ID thru a redirect or reloaded?
For me, that was a long run but now here's the deal.
In this example, we have two servers, one for login and the other for processing the credentials. Remember, they are both child domains.

Server 1: auth.domain.com
Server 2: web.domain.com

You login in a page on auth.domain.com. You have to start your a session with:
<?php
$anything = session_name("nostromo"); // that's the point
session_set_cookie_params(0, '/', '.domain.com'); // It's pretty funny that MSIE will need this but FF and Chrome won't.
session_start();
echo "ID: ".session_id(); // check your id
[.......authentication and other security stuff......]
header ('Location: http://web.domain.com/index.php?'.$mysecurestring ); // mysecurestring contains some encrypted data, including my session_id
?>

On web.domain.com:
<?php
 [...]
if ( isset( $_GET['id'] ) && !empty( $_GET['id'] )){
[....decrypting and validating your data, logging etc...and:]
session_id($my_received_secured_session_id);
   echo '<script>
     window.location = window.location.href.split("?")[0];
        </script>';
}
else {
$anything = session_name("nostromo");
session_start();
echo "We happy Vincent? ".session_id();
    }
?>

Getting work this single piece of code has taken me two hectic days.