Friday, December 3, 2010

SPWebApplication.Lookup() throws "This operation can be performed only on a computer that is joined to a server farm..."

In my case, issue was that project's target platform was x86. Changed it to 'Any CPU' and it worked.

Tuesday, September 7, 2010

ASP.Net Error: "The requested content appears to be script and will not be served by the static file handler"

This means that, while there exist a handler that maps to that type of content (e.g. aspx), it doesn't apply to currently used .NET Framework.
Solution is to run aspnet_regiis.exe -i for the current framework. (e.g. C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i)
If that doesn't work, then double check whether there's a handler that maps to that content for integrated pipeline mode. If there's not, a possible solution is to change to classic pipeline mode.

Wednesday, August 25, 2010

PowerShell: Storing and retrieving secrets

function StoreSecret($plain, $subkeyPath, $secretRegValue)
{
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Security")
$secret = [System.Security.Cryptography.ProtectedData]::Protect([System.Text.Encoding]::UTF7.GetBytes($plain), $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
$subkey=[Microsoft.Win32.Registry]::LocalMachine.CreateSubKey($subkeyPath)
[void]$subkey.SetValue($secretRegValue, $secret, [Microsoft.Win32.RegistryValueKind]::Binary)
}

function RetrieveSecret($subkeyPath, $secretRegValue)
{
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Security")
$secret = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($subkeyPath).GetValue($secretRegValue)
$plain = [System.Text.Encoding]::UTF7.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($secret, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser))
return $plain
}

# set needed constants
$subkeyPath = "Software\Pepino";
$secretRegValue = "Secret";

function StoreMySecret($plain)
{
StoreSecret -plain $plain -subkeyPath $subkeyPath -secretRegValue $secretRegValue
}

function RetrieveMySecret()
{
$plain = RetrieveSecret -subkeyPath $subkeyPath -secretRegValue $secretRegValue
return $plain
}

# store secret
$plain="boquita"
Write-Host "Secret is `"$plain`"" -BackgroundColor Black -ForegroundColor Yellow
StoreMySecret -plain $plain

# retrieve secret
$plain = RetrieveMySecret
Write-Host "Recovered secret is `"$plain`"" -BackgroundColor Black -ForegroundColor Yellow

Thursday, August 19, 2010

SQL Server: Backup/Restore sample PowerShell script

This is a sample script that demonstrates a typical recovery scenario in SQL Server: full, differential and log backups restored in that order to bring back a database online.

(A pre-requisite to run it is to have SQL Server snap-ins added to PowerShell. See here.)

### SCRIPT STARTS HERE
$instance='.\SQLEXPRESS'

# drop db
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;IF DB_ID('DUMMY') IS NOT NULL ALTER DATABASE DUMMY SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;IF DB_ID('DUMMY') IS NOT NULL DROP DATABASE DUMMY"

# create db with a table
$filesDir="c:\Garbage"
if(-not(test-path $filesDir)){mkdir $filesDir}
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;CREATE DATABASE DUMMY ON (NAME = DUMMY_DATA,FILENAME='$filesDir\DUMMY_DATA.MDF') LOG ON (NAME = DUMMY_LOG, FILENAME = '$filesDir\DUMMY_LOG.LDF')"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;ALTER DATABASE DUMMY SET RECOVERY FULL"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;CREATE TABLE DATA(VALUE SMALLINT)"

# query db (and ignore error)
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;SELECT VALUE FROM DATA" -EA "SILENTLYCONTINUE"

# insert some rows
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;INSERT INTO DATA(VALUE) VALUES(1)"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;INSERT INTO DATA(VALUE) VALUES(2)"

# query db
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;SELECT VALUE FROM DATA"

# full backup
$full="$filesDir\Full.bak"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;BACKUP DATABASE DUMMY TO DISK='$full'"

# PROBLEM HERE, SOMEONE MISTAKENLY DROPS DATABASE
# drop db
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;ALTER DATABASE DUMMY SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;DROP DATABASE DUMMY"

# TEST: restore full backup and verify data is there
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;RESTORE DATABASE DUMMY FROM DISK='$full'"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;SELECT VALUE FROM DATA" -EA "SILENTLYCONTINUE"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;SELECT VALUE FROM DATA"

# insert a row
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;INSERT INTO DATA(VALUE) VALUES(3)"

# backup a transaction log
$diff="$filesDir\Differential.bak"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;BACKUP DATABASE DUMMY TO DISK='$DIFF' WITH DIFFERENTIAL"

# insert another row
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;INSERT INTO DATA(VALUE) VALUES(4)"

# backup another transaction log
$log="C:\Garbage\Log.bak"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;BACKUP LOG DUMMY TO DISK='$log'"

# drop database
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;ALTER DATABASE DUMMY SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;DROP DATABASE DUMMY"

# verify no data files are in place
dir $filesDir\*.mdf;dir $filesDir\*.ldf

# TEST: restore full backup plus the transactions logs and verify data is there
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;RESTORE DATABASE DUMMY FROM DISK='$full' WITH NORECOVERY"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;RESTORE DATABASE DUMMY FROM DISK='$diff' WITH NORECOVERY"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE MASTER;RESTORE LOG DUMMY FROM DISK='$log'"

# query db, we should have now 4 rows!
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;SELECT VALUE FROM DATA" -EA "SILENTLYCONTINUE"
Invoke-Sqlcmd -ServerInstance $instance -Query "USE DUMMY;SELECT VALUE FROM DATA"

# and we should have data and log files back
dir $filesDir\*.mdf;dir $filesDir\*.ldf

### SCRIPT ENDS HERE

Wednesday, August 18, 2010

Shortcut for generating a hotfix request for MS

KB#

Windbg: investigating exceptions

The sequence shown below is:

1) !dumpheap -type Exception
2) !dumpheap -type System.Runtime.InteropServices.COMException
3) !pe 0000000006a58fb8
4) !do 0000000006a58fb8 (for some specific fields that !pe won't show)

0:000> !dumpheap -type Exception
Address MT Size
0000000006961048 000007fef3336b30 136
00000000069610d0 000007fef3336c40 136
0000000006961158 000007fef3336d50 136
00000000069611e0 000007fef3336e60 136
0000000006961268 000007fef3336e60 136
0000000006a29a90 000007fef3340298 24
0000000006a29ac0 000007fef3340310 24
0000000006a58fb8 000007fef335c580 136
0000000006ac4390 000007fef335c580 136
total 9 objects
Statistics:
MT Count TotalSize Class Name
000007fef3340310 1 24 System.Text.DecoderExceptionFallback
000007fef3340298 1 24 System.Text.EncoderExceptionFallback
000007fef3336d50 1 136 System.ExecutionEngineException
000007fef3336c40 1 136 System.StackOverflowException
000007fef3336b30 1 136 System.OutOfMemoryException
000007fef335c580 2 272 System.Runtime.InteropServices.COMException
000007fef3336e60 2 272 System.Threading.ThreadAbortException
Total 9 objects

0:000> !dumpheap -type System.Runtime.InteropServices.COMException
Address MT Size
0000000006a58fb8 000007fef335c580 136
0000000006ac4390 000007fef335c580 136
total 2 objects
Statistics:
MT Count TotalSize Class Name
000007fef335c580 2 272 System.Runtime.InteropServices.COMException
Total 2 objects

0:000> !do 0000000006a58fb8
Name: System.Runtime.InteropServices.COMException
MethodTable: 000007fef335c580
EEClass: 000007fef2f4a2f8
Size: 136(0x88) bytes
(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
000007fef3336758 40000b5 8 System.String 0 instance 0000000000000000 _className
000007fef3334b00 40000b6 10 ...ection.MethodBase 0 instance 0000000000000000 _exceptionMethod
000007fef3336758 40000b7 18 System.String 0 instance 0000000000000000 _exceptionMethodString
000007fef3336758 40000b8 20 System.String 0 instance 0000000006a591d8 _message
000007fef332dd78 40000b9 28 ...tions.IDictionary 0 instance 0000000000000000 _data
000007fef3336a20 40000ba 30 System.Exception 0 instance 0000000000000000 _innerException
000007fef3336758 40000bb 38 System.String 0 instance 0000000006a59268 _helpURL
000007fef3336048 40000bc 40 System.Object 0 instance 0000000006a59328 _stackTrace
000007fef3336758 40000bd 48 System.String 0 instance 0000000000000000 _stackTraceString
000007fef3336758 40000be 50 System.String 0 instance 0000000000000000 _remoteStackTraceString
000007fef333d9c8 40000bf 70 System.Int32 1 instance 0 _remoteStackIndex
000007fef3336048 40000c0 58 System.Object 0 instance 0000000000000000 _dynamicMethods
000007fef333d9c8 40000c1 74 System.Int32 1 instance -2146824040 _HResult
000007fef3336758 40000c2 60 System.String 0 instance 0000000006a592a8 _source
000007fef3339160 40000c3 68 System.IntPtr 1 instance 0 _xptrs
000007fef333d9c8 40000c4 78 System.Int32 1 instance -532459699 _xcode

0:000> !pe 0000000006a58fb8
Exception object: 0000000006a58fb8
Exception type: System.Runtime.InteropServices.COMException
Message: This command is not available because no document is open.
InnerException: <none>
StackTrace (generated):
SP IP Function
000000000013A200 0000000000000001 Microsoft_Office_Interop_Word!Microsoft.Office.Interop.Word.ApplicationClass.get_ActiveDocument()+0x2
000000000013A2F0 000007FF00222F6E Ms_Ddue_DdueWord!Microsoft.Ddue.DdueWordAuthoring.WordHelper.GetActiveDocument(Microsoft.Office.Interop.Word.Application)+0xce

StackTraceString: <none>
HResult: 800a1098


See here for more details.

Friday, August 13, 2010

PowerShell, double and single quotes

Powershell and quotes can be a bit confusing sometimes.

Double-quoted strings are subject to variable substitution, while single-quoted strings are not.

For example, let's launch a PowerShell console:

C:\Users\User>$x="hello"
C:\Users\User>"$x"
hello
C:\Users\User>'$x'
$x
C:\Users\User>
Let's write now a very small script that outputs a single parameter:

C:\Users\User>'param($p) "$p"' > .\test.ps1
C:\Users\User>type .\test.ps1
param($p) "$p"

Here's the output when calling that script with double- and single-quoted strings:

C:\Users\User>$x="hello"
C:\Users\User>.\test.ps1 "$x"
hello
C:\Users\User>.\test.ps1 '$x'
$x
C:\Users\User>.\test.ps1 -p "hello world"
hello world
C:\Users\User>.\test.ps1 -p 'hello world'
hello world
Which makes sense, because in PowerShell both single and double quotes serve to form strings with spaces.

Now, let's open a normal command prompt and try a few things:

C:\Users\User>powershell -file test.ps1 -p "hello"
hello
C:\Users\User>powershell -file test.ps1 -p 'hello'
'hello'
C:\Users\User>set XYZ="hello world"
C:\Users\User>powershell -file .\test.ps1 %XYZ%
hello world
C:\Users\User>set XYZ='hello world'
C:\Users\User>powershell -f .\test.ps1 %XYZ%
'hello
Which is expected too, because in a DOS command prompt, only double quotes will form strings with spaces, and single-quotes are taken as literals.

Tuesday, March 9, 2010

EDM designer in Visual Studio: "The operation could not be completed. The parameter is incorrect"

When trying to open a .edmx file in VS, it throws this error:



Solution: open the designer as plain xml and remove children of edmx:Diagrams/Diagram node.

EDM: Error 11011: Association End key property 'Id' is not mapped.

Problem: receiving this error when building a project that includes an EDM:
Error 11011: Association End key property 'Id' is not mapped.
Solution: open as plain xml the .edmx file, remove everything related to the entity causing the error, then open the model with the designer and "Update model from database..." After you build, you should not get this error anymore.

Thursday, March 4, 2010

MVC & ViewState don't work together

It seems that postbacks are not supported in MVC. I found this article, and tried to address this issue in order to use some Ajax controls that do require form tags for including a ScriptManager, which cause postbacks.

In short - it worked correctly, with one tweak: instead of
public class ViewUserControlWithoutViewState<T> : ViewUserControl<T> where T : class 
I changed to:
public class ViewUserControlWithoutViewState : ViewUserControl
Otherwise, ASP.Net was not finding the type. Why? Didn't dig into more, but it may be related to Reflection not resolving correctly when where keyword is being used.

BTW - this is the control I was trying to use (needs Ajax Controls Toolkit):
    <form id="Form1" runat="server">
<asp:ToolkitScriptManager ID="asm" runat="server" />
<asp:LinkButton ID="linkButton1" runat="server" Text="Show Popup" />
<asp:ConfirmButtonExtender ID="ConfirmButtonExtender1" runat="server" TargetControlID="linkButton1" ConfirmText="Want it or not?" />
</form>

Tuesday, January 12, 2010

Reindex script for SQL Server

DECLARE @db_name nvarchar(1000)
SET @db_name=N'your database name'
EXEC ('USE ' + @db_name)
DECLARE @index_name nvarchar(1000)
DECLARE @table_name nvarchar(1000)
DECLARE @ind_id int
DECLARE index_cursor CURSOR for
select name, object_name(id), indid from sysindexes where id > 1000 and indid >=1 and rows > 0 order by object_name(id), indid, name
OPEN index_cursor
FETCH NEXT FROM index_cursor INTO @index_name, @table_name, @ind_id
WHILE @@FETCH_STATUS = 0
BEGIN
IF @ind_id = 1
BEGIN
EXEC sp_executesql N'DBCC DBREINDEX (@tbl, @idx, 0)',
N'@idx nvarchar(1000), @tbl nvarchar(1000)',
@index_name,
@table_name
END
EXEC sp_executesql N'DBCC INDEXDEFRAG (@db, @tbl, @idx)',
N'@db nvarchar(1000), @idx nvarchar(1000), @tbl nvarchar(1000)',
@db_name,
@index_name,
@table_name
FETCH NEXT FROM index_cursor INTO @index_name, @table_name, @ind_id
END
CLOSE index_cursor
DEALLOCATE index_cursor